Promise.all में त्रुटियों को संभालना


265

मेरे पास वादे का एक सरणी है जिसे मैं हल कर रहा हूं Promise.all(arrayOfPromises);

मैं वादा श्रृंखला जारी रखने के लिए आगे बढ़ता हूं। कुछ ऐसा दिखता है

existingPromiseChain = existingPromiseChain.then(function() {
  var arrayOfPromises = state.routes.map(function(route){
    return route.handler.promiseHandler();
  });
  return Promise.all(arrayOfPromises)
});

existingPromiseChain = existingPromiseChain.then(function(arrayResolved) {
  // do stuff with my array of resolved promises, eventually ending with a res.send();
});

मैं त्रुटियों के मामले में एक व्यक्तिगत वादे को संभालने के लिए एक कैच स्टेटमेंट जोड़ना चाहता हूं, लेकिन जब मैं कोशिश करता हूं, तो Promise.allवह पहली त्रुटि पाता है जो उसे मिलती है (बाकी की अवहेलना करता है), और फिर मैं बाकी वादों से डेटा प्राप्त नहीं कर सकता सरणी (जो त्रुटि नहीं थी)।

मैंने कुछ ऐसा करने की कोशिश की है ..

existingPromiseChain = existingPromiseChain.then(function() {
      var arrayOfPromises = state.routes.map(function(route){
        return route.handler.promiseHandler()
          .then(function(data) {
             return data;
          })
          .catch(function(err) {
             return err
          });
      });
      return Promise.all(arrayOfPromises)
    });

existingPromiseChain = existingPromiseChain.then(function(arrayResolved) {
      // do stuff with my array of resolved promises, eventually ending with a res.send();
});

लेकिन वह हल नहीं करता है।

धन्यवाद!

-

संपादित करें:

नीचे दिए गए जवाब क्या थे, पूरी तरह से सच थे, कोड अन्य कारणों से टूट रहा था। मामले में किसी को भी दिलचस्पी है, यह समाधान मैं के साथ समाप्त हो गया है ...

नोड एक्सप्रेस सर्वर चेन

serverSidePromiseChain
    .then(function(AppRouter) {
        var arrayOfPromises = state.routes.map(function(route) {
            return route.async();
        });
        Promise.all(arrayOfPromises)
            .catch(function(err) {
                // log that I have an error, return the entire array;
                console.log('A promise failed to resolve', err);
                return arrayOfPromises;
            })
            .then(function(arrayOfPromises) {
                // full array of resolved promises;
            })
    };

एपीआई कॉल (मार्ग.संकल्प कॉल)

return async()
    .then(function(result) {
        // dispatch a success
        return result;
    })
    .catch(function(err) {
        // dispatch a failure and throw error
        throw err;
    });

लगता है कि मूल वादों से किसी भी त्रुटि को पकड़ने के उद्देश्य से सेवा के .catchलिए Promise.allपहले डाल दिया .then, लेकिन फिर अगले करने के लिए पूरे सरणी वापस.then

धन्यवाद!


2
आपका प्रयास ऐसा लगता है कि यह काम करना चाहिए ... हो सकता है कि बाद में कहीं और कोई समस्या हो?
Ry-

.then(function(data) { return data; })पूरी तरह से छोड़ दिया जा सकता है
बर्गी

केवल यही कारण है कि ऊपर का समाधान नहीं होना चाहिए, यदि आप हमें thenया catchहैंडलर में सभी कोड नहीं दिखा रहे हैं और अंदर एक त्रुटि हो रही है। वैसे, क्या यह नोड है?

1
आपकी "मौजूदा श्रृंखला" में आपकी कोई अंतिम पकड़ नहीं है, इसलिए ऐसी त्रुटियां हो सकती हैं जिन्हें आप नहीं देख रहे हैं जो यह बता सकती हैं कि यह "क्यों हल नहीं होता है"। उसे जोड़ने का प्रयास करें और देखें कि आपको क्या त्रुटि मिलती है।
जिब

जवाबों:


189

Promise.allसभी या कुछ भी नहीं है। यह एक बार सरणी हल में सभी वादों को हल करता है, या जैसे ही उनमें से एक खारिज कर देता है। दूसरे शब्दों में, यह या तो सभी हल किए गए मानों की एक सरणी के साथ हल होता है, या एक त्रुटि के साथ अस्वीकार करता है।

कुछ पुस्तकालयों में कुछ कहा जाता है Promise.when, जिसे मैं समझता हूं कि इसके बजाय सरणी में सभी वादों के लिए या तो हल करने या अस्वीकार करने की प्रतीक्षा करेंगे, लेकिन मैं इससे परिचित नहीं हूं, और यह ईएस 6 में नहीं है।

तुम्हारा कोड

मैं यहां दूसरों से सहमत हूं कि आपका फिक्स काम करना चाहिए। इसे ऐसे सरणी के साथ हल करना चाहिए जिसमें सफल मूल्यों और त्रुटियों वाली वस्तुओं का मिश्रण हो सकता है। सफलता-पथ में त्रुटि वस्तुओं को पारित करना असामान्य है लेकिन यह मानते हुए कि आपका कोड उनसे उम्मीद कर रहा है, मुझे इसमें कोई समस्या नहीं है।

एकमात्र कारण जो मैं सोच सकता हूं कि यह "हल नहीं होगा" यह है कि यह कोड में विफल हो रहा है आप हमें नहीं दिखा रहे हैं और इसका कारण यह है कि आप इस बारे में कोई त्रुटि संदेश नहीं देख रहे हैं क्योंकि यह वादा श्रृंखला अंतिम के साथ समाप्त नहीं हुई है पकड़ (जहाँ तक आप हमें वैसे भी दिखा रहे हैं)।

मैंने आपके उदाहरण से "मौजूदा चेन" को बाहर निकालने और एक कैच के साथ चेन को समाप्त करने की स्वतंत्रता ली है। यह आपके लिए सही नहीं हो सकता है, लेकिन इसे पढ़ने वाले लोगों के लिए, यह हमेशा महत्वपूर्ण है कि या तो चेन लौटाएं या समाप्त करें, या संभावित त्रुटियां, यहां तक ​​कि कोडिंग त्रुटियां, छिपी हो जाएंगी (जो कि मुझे यहां संदेह हुआ है):

Promise.all(state.routes.map(function(route) {
  return route.handler.promiseHandler().catch(function(err) {
    return err;
  });
}))
.then(function(arrayOfValuesOrErrors) {
  // handling of my array containing values and/or errors. 
})
.catch(function(err) {
  console.log(err.message); // some coding error in handling happened
});

4
आप (और उपरोक्त टिप्पणी) सही थे। मेरा मार्ग .handler.promiseHandler .catch () और त्रुटि वापस करने की आवश्यकता है। मुझे श्रृंखला के अंतिम .catch () को जोड़ने की भी आवश्यकता थी। श्रृंखला के हर चरण में सफलता / त्रुटि संचालकों के महत्व को रिले करने के लिए धन्यवाद :)।
जॉन

2
मुझे यह भी पता चला है कि अगर मैं अपने .catch () रूट के लिए त्रुटि को फेंक दूं। यदि मैं इसके बजाय त्रुटि वापस करता हूं, तो यह वही करेगा जो मैं चाहता हूं और संपूर्ण सरणी को संभालता हूं।
जॉन

2
Promise.allSettled()सभ्य समर्थन के साथ अब एक मानक तरीका है । संदर्भ देखें ।
आंद्रे माउगर

हाँ, Promise.allविफल रहता है, जब पहला धागा विफल रहता है। लेकिन दुर्भाग्य से सभी अन्य धागे अभी भी चलते हैं जब तक कि वे खत्म नहीं हो जाते। कुछ भी रद्द नहीं किया गया है, इससे भी बदतर: एक धागा को रद्द करने का कोई तरीका नहीं है Promise। इसलिए जो भी थ्रेड्स कर रहे हैं (और जोड़ तोड़) वे जारी रखते हैं, वे राज्यों और चर को बदलते हैं, वे सीपीयू का उपयोग करते हैं, लेकिन अंत में वे अपना परिणाम वापस नहीं करते हैं। जब आप कॉल दोहराते / पुनः प्रयास करते हैं, तो अराजकता उत्पन्न करने के लिए आपको इसके बारे में पता होना चाहिए।
मार्क वैकरलिन

143

नया जवाब

const results = await Promise.all(promises.map(p => p.catch(e => e)));
const validResults = results.filter(result => !(result instanceof Error));

भविष्य का वादा एपीआई

  • Chrome 76: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled
  • इसे प्राप्त करने के लिए आप https://www.npmjs.com/package/promise.allsettled डाउनलोड कर सकते हैं। कुछ ब्राउज़रों में ऑलसेट्ड ब्राउज़र के साथ ही प्रीइंस्टॉल्ड आता है। यह मन की शांति के लिए पैकेज डाउनलोड करने के लायक है क्योंकि उदा। टाइपस्क्रिप्ट में AllSettled के लिए डिफ़ॉल्ट परिभाषा नहीं है।

11
हालांकि eएक होना जरूरी नहीं है Error। यह एक स्ट्रिंग हो सकता है, उदाहरण के लिए, यदि कोई इसे पसंद करता है Promise.reject('Service not available')
केलसुन

@ArturKlesun हम फिर कैसे वर्गीकृत कर सकते हैं कि किस वादे के परिणामस्वरूप त्रुटि हुई और जो नहीं हुई?
शुभम जैन

5
@ के साथ शुभम-जैन .then()और .catch()Promise.resolve()पूर्व को मान Promise.reject()देगा , जबकि इसे बाद में पास करेगा। आप उन्हें उदाहरण के लिए वस्तु में लपेट सकते हैं p.then(v => ({success: true, value: v})).catch(e => ({success: false, error: e})):।
क्लेसुन

2
आप परिणामों को क्यों फ़िल्टर करेंगे? इसका कोई मतलब नहीं है अगर आप परिणामों के साथ कुछ भी कर रहे हैं - आपको यह जानने के लिए आदेश की आवश्यकता है कि कौन सा रिटर्न किस मूल्य से है!
रयान टेलर

21

Promise.allलूप को जारी रखने के लिए (यहां तक ​​कि जब एक वादा खारिज होता है) मैंने एक उपयोगिता फ़ंक्शन लिखा था जिसे कहा जाता है executeAllPromises। यह उपयोगिता समारोह के साथ एक वस्तु देता है resultsऔर errors

विचार यह है कि आपके द्वारा पारित सभी वादे executeAllPromisesएक नए वादे में लिपटे रहेंगे जो हमेशा हल होंगे। नया वादा एक सरणी के साथ हल होता है जिसमें 2 स्पॉट होते हैं। पहला स्थान रिज़ॉल्यूशन मान (यदि कोई हो) रखता है और दूसरा स्थान त्रुटि रखता है (यदि लिपटे वादे को अस्वीकार कर दिया जाता है)।

एक अंतिम चरण के रूप executeAllPromisesमें लिपटे वादों के सभी मूल्यों को संचित किया जाता है और अंतिम ऑब्जेक्ट के लिए एक सरणी resultsऔर के लिए एक सरणी के साथ रिटर्न करता है errors

यहाँ कोड है:

function executeAllPromises(promises) {
  // Wrap all Promises in a Promise that will always "resolve"
  var resolvingPromises = promises.map(function(promise) {
    return new Promise(function(resolve) {
      var payload = new Array(2);
      promise.then(function(result) {
          payload[0] = result;
        })
        .catch(function(error) {
          payload[1] = error;
        })
        .then(function() {
          /* 
           * The wrapped Promise returns an array:
           * The first position in the array holds the result (if any)
           * The second position in the array holds the error (if any)
           */
          resolve(payload);
        });
    });
  });

  var errors = [];
  var results = [];

  // Execute all wrapped Promises
  return Promise.all(resolvingPromises)
    .then(function(items) {
      items.forEach(function(payload) {
        if (payload[1]) {
          errors.push(payload[1]);
        } else {
          results.push(payload[0]);
        }
      });

      return {
        errors: errors,
        results: results
      };
    });
}

var myPromises = [
  Promise.resolve(1),
  Promise.resolve(2),
  Promise.reject(new Error('3')),
  Promise.resolve(4),
  Promise.reject(new Error('5'))
];

executeAllPromises(myPromises).then(function(items) {
  // Result
  var errors = items.errors.map(function(error) {
    return error.message
  }).join(',');
  var results = items.results.join(',');
  
  console.log(`Executed all ${myPromises.length} Promises:`);
  console.log(`— ${items.results.length} Promises were successful: ${results}`);
  console.log(`— ${items.errors.length} Promises failed: ${errors}`);
});


2
यह सरल किया जा सकता है। देखें stackoverflow.com/a/36115549/918910
jib

18

ES2020 वादा प्रकार के लिए नई विधि का परिचय देता है : Promise.allSettled Promise.allSettled()
आपको एक संकेत देता है जब सभी इनपुट वादों का निपटारा किया जाता है, जिसका अर्थ है कि वे या तो पूर्ण हो चुके हैं या अस्वीकार कर दिए गए हैं। यह उन मामलों में उपयोगी है जहां आप वादे की स्थिति के बारे में परवाह नहीं करते हैं, आप बस यह जानना चाहते हैं कि काम कब किया जाता है, चाहे वह सफल हो।

const promises = [
  fetch('/api-call-1'),
  fetch('/api-call-2'),
  fetch('/api-call-3'),
];
// Imagine some of these requests fail, and some succeed.

const result = await Promise.allSettled(promises);
console.log(result.map(x=>s.status));
// ['fulfilled', 'fulfilled', 'rejected']

V8 ब्लॉग पोस्ट में और पढ़ें https://v8.dev/features/promise-combinators


13

जैसा @ ज़िब ने कहा,

Promise.all सभी या कुछ भी नहीं है।

हालाँकि, आप कुछ ऐसे वादों को नियंत्रित कर सकते हैं जिन्हें "विफल" होने की अनुमति है और हम आगे बढ़ना चाहते हैं .then

उदाहरण के लिए।

  Promise.all([
    doMustAsyncTask1,
    doMustAsyncTask2,
    doOptionalAsyncTask
    .catch(err => {
      if( /* err non-critical */) {
        return
      }
      // if critical then fail
      throw err
    })
  ])
  .then(([ mustRes1, mustRes2, optionalRes ]) => {
    // proceed to work with results
  })

6

अगर आपको q लाइब्रेरी का उपयोग करने के लिए मिलता है https://github.com/kriskowal/q इसमें q.allSettled () विधि है जो इस समस्या को हल कर सकती है जो आप अपने राज्य के आधार पर हर वादे को संभाल सकते हैं या तो पूर्ण रूप से अस्वीकृत या अस्वीकृत कर सकते हैं।

existingPromiseChain = existingPromiseChain.then(function() {
var arrayOfPromises = state.routes.map(function(route){
  return route.handler.promiseHandler();
});
return q.allSettled(arrayOfPromises)
});

existingPromiseChain = existingPromiseChain.then(function(arrayResolved) {
//so here you have all your promises the fulfilled and the rejected ones
// you can check the state of each promise
arrayResolved.forEach(function(item){
   if(item.state === 'fulfilled'){ // 'rejected' for rejected promises
     //do somthing
   } else {
     // do something else
   }
})
// do stuff with my array of resolved promises, eventually ending with a res.send();
});

चूंकि आप कुछ लाइब्रेरी ( q) का उपयोग करने का सुझाव दे रहे हैं , इसलिए यह अधिक उपयोगी होगा यदि आप प्रश्न से संबंधित उपयोग उदाहरण प्रदान करते हैं। जैसा कि यह खड़ा है, आपका जवाब यह नहीं बताता है कि यह पुस्तकालय समस्या को हल करने में कैसे मदद कर सकता है।
ishmelMakitla

सुझाव के अनुसार एक उदाहरण जोड़ा
मोहम्मद महमूद

1
सरका 2018 को हमेशा देखना चाहिए कि सिंद्रे ने :-) क्या उपलब्ध है। github.com/sindresorhus/p-settle । सिंद्रे के एकल उद्देश्य मॉड्यूल के साथ आपको केवल एक बिट के लिए q जैसे विशाल पुस्तकालय को आयात करने की आवश्यकता नहीं है।
DKebler

6

Async प्रतीक्षा का उपयोग करना -

यहाँ एक async फ़ंक्शन func1 एक हल किया हुआ मान लौटा रहा है, और func2 एक त्रुटि फेंक रहा है और इस स्थिति में एक अशक्त वापसी कर रहा है, हम इसे संभाल सकते हैं कि हम कैसे चाहते हैं और उसी के अनुसार वापस लौट सकते हैं।

const callingFunction  = async () => {
    const manyPromises = await Promise.all([func1(), func2()]);
    console.log(manyPromises);
}


const func1 = async () => {
    return 'func1'
}

const func2 = async () => {
    try {
        let x;
        if (!x) throw "x value not present"
    } catch(err) {
       return null
    }
}

callingFunction();

आउटपुट है - ['func1', null]


4

ES8 का उपयोग करने वालों के लिए जो यहाँ ठोकर खाते हैं, आप निम्न कार्य कर सकते हैं, async फ़ंक्शंस का उपयोग करके :

var arrayOfPromises = state.routes.map(async function(route){
  try {
    return await route.handler.promiseHandler();
  } catch(e) {
    // Do something to handle the error.
    // Errored promises will return whatever you return here (undefined if you don't return anything).
  }
});

var resolvedPromises = await Promise.all(arrayOfPromises);

3

हम अलग-अलग वादों के स्तर पर अस्वीकृति को संभाल सकते हैं, इसलिए जब हम अपने परिणाम सरणी में परिणाम प्राप्त करते हैं, तो अस्वीकार किया गया सरणी सूचकांक होगा undefined। हम उस स्थिति को आवश्यकतानुसार संभाल सकते हैं, और शेष परिणामों का उपयोग कर सकते हैं।

यहां मैंने पहला वादा अस्वीकार कर दिया है, इसलिए यह अपरिभाषित के रूप में आता है, लेकिन हम दूसरे वादे के परिणाम का उपयोग कर सकते हैं, जो सूचकांक 1 पर है।

const manyPromises = Promise.all([func1(), func2()]).then(result => {
    console.log(result[0]);  // undefined
    console.log(result[1]);  // func2
});

function func1() {
    return new Promise( (res, rej) => rej('func1')).catch(err => {
        console.log('error handled', err);
    });
}

function func2() {
    return new Promise( (res, rej) => setTimeout(() => res('func2'), 500) );
}


यदि हम async प्रतीक्षा का उपयोग करते हैं तो आप एक समान काम कैसे कर सकते हैं?
रुद्रेश अजगांवकर

मैंने आपके प्रश्न का उत्तर दे दिया है, कृपया उत्तर के लिए लिंक ढूंढें। stackoverflow.com/a/55216763/4079716
नयन पटेल

2

क्या आपने विचार किया Promise.prototype.finally()?

ऐसा लगता है कि जैसा आप चाहते हैं वैसा ही करने के लिए डिज़ाइन किया गया है - सभी वादों के निपटारे (निराकृत / अस्वीकृत) हो जाने के बाद किसी फ़ंक्शन को निष्पादित करें, भले ही कुछ वादों को अस्वीकार कर दिया जाए।

से MDN दस्तावेजीकरण :

finally()यदि आप वादे का निपटारा करते हैं, तो इसके परिणाम की परवाह किए बिना यदि आप कुछ प्रसंस्करण या सफाई करना चाहते हैं तो यह विधि उपयोगी हो सकती है।

finally()विधि बहुत बुला के समान है .then(onFinally, onFinally)लेकिन वहाँ मतभेद की जोड़ी हैं:

एक फ़ंक्शन इनलाइन बनाते समय, आप इसे दो बार घोषित करने के लिए मजबूर होने के बजाय एक बार इसे पारित कर सकते हैं, या इसके लिए एक चर बना सकते हैं।

आखिरकार कॉलबैक को कोई तर्क नहीं मिलेगा, क्योंकि यह निर्धारित करने का कोई विश्वसनीय साधन नहीं है कि क्या वादा पूरा हुआ या खारिज कर दिया गया। यह उपयोग मामला ठीक तब के लिए है जब आप अस्वीकृति के कारण, या पूर्ति मूल्य की परवाह नहीं करते हैं, और इसलिए इसे प्रदान करने की कोई आवश्यकता नहीं है।

इसके विपरीत Promise.resolve(2).then(() => {}, () => {})(जिसे अपरिभाषित के साथ हल किया Promise.resolve(2).finally(() => {})जाएगा ), 2 के साथ हल किया जाएगा। इसी तरह, इसके विपरीत Promise.reject(3).then(() => {}, () => {})(जो अपरिभाषित के साथ पूरा हो जाएगा), Promise.reject(3).finally(() => {})3 के साथ खारिज कर दिया जाएगा।

== पतन ==

यदि जावास्क्रिप्ट का आपका संस्करण समर्थन नहीं करता है, Promise.prototype.finally()तो आप जेक आर्किबाल्ड से इस समाधान का उपयोग कर सकते हैं :Promise.all(promises.map(p => p.catch(() => undefined)));


1
हां, जब तक Promises.allSettled()वास्तव में लागू नहीं किया जाता है (यह यहां एमडीएन द्वारा प्रलेखित है ), तब Promises.all.finally()वही बात पूरी होगी। मैं इसे एक कोशिश देने वाला हूं ...
जाम

@jamess आप इस टिप्पणी को एक उचित जवाब के रूप में क्यों नहीं बनाते हैं? कोई भी उत्तर ईएस 6 का संदर्भ नहीं देता है allSettled()
प्रवीण

@ प्रवीण - जो मैं बता सकता हूं, allSettled()वह कहीं भी (अभी तक) लागू नहीं है, इसलिए मैं वास्तविकता से आगे नहीं जाना चाहता। मुझे Promises.all(myPromiseArray).finally()इस उत्तर के साथ सफलता मिली । एक बार allSettled()वास्तव में मौजूद होने के बाद, मैं इसका परीक्षण कर सकता हूं और यह पता लगा सकता हूं कि यह वास्तव में कैसे काम करता है। तब तक, कौन जानता है कि ब्राउज़र वास्तव में क्या लागू करेंगे? जब तक आपके पास इसके विपरीत हाल की जानकारी नहीं है ...
जाम

@ जैमेस यह सच है कि अभी भी ड्राफ्ट चरण में है .. हालांकि नवीनतम एफएफ और क्रोम इसे पूरी तरह से समर्थन करते प्रतीत होते हैं .. यह स्थिरता के बारे में निश्चित नहीं है .. मोज़िला डॉक्स वैसे भी मैं जिस बिंदु को बनाने की कोशिश कर रहा था वह यह था कि इसे खोजने में बहुत आसान होगा अगर यह एक टिप्पणी से एक उत्तर था .. यह उर कॉल हालांकि :)
प्रवीण

@ प्रवीण - जिस समय मैंने अपनी टिप्पणी पोस्ट की, उस समय इसे कहीं भी लागू नहीं किया गया था। मैंने अभी फ़ायरफ़ॉक्स और क्रोम में परीक्षण किया है: Promise.allSettledफ़ायरफ़ॉक्स में लागू नहीं किया गया है, लेकिन यह क्रोम में मौजूद है। सिर्फ इसलिए कि डॉक्स कहते हैं कि यह लागू है इसका मतलब यह नहीं है कि यह वास्तव में लागू किया गया है। मैं इसे जल्द ही कभी भी उपयोग नहीं करने जा रहा हूं।
13

0

वैकल्पिक रूप से, यदि आपके पास एक ऐसा मामला है जहां आप विशेष रूप से हल किए गए वादों के मूल्यों के बारे में परवाह नहीं करते हैं, जब एक विफलता होती है, लेकिन आप अभी भी उन्हें चलाना चाहते हैं, तो आप कुछ ऐसा कर सकते हैं जो सामान्य होने पर वादों के साथ हल होगा। वे सभी सफल होते हैं और असफल वादों को अस्वीकार करते हैं जब उनमें से कोई भी विफल हो जाता है:

function promiseNoReallyAll (promises) {
  return new Promise(
    async (resolve, reject) => {
      const failedPromises = []

      const successfulPromises = await Promise.all(
        promises.map(
          promise => promise.catch(error => {
            failedPromises.push(error)
          })
        )
      )

      if (failedPromises.length) {
        reject(failedPromises)
      } else {
        resolve(successfulPromises)
      }
    }
  )
}

0

आप हमेशा अपने वादे को पूरा करने वाले कार्यों को इस तरह से लपेट सकते हैं कि वे विफलता को पकड़ते हैं और एक सहमत मूल्य (जैसे error.message) के बजाय वापसी करते हैं, इसलिए अपवाद Promise.all फ़ंक्शन तक सभी तरह से रोल नहीं करेगा और इसे अक्षम करेगा।

async function resetCache(ip) {

    try {

        const response = await axios.get(`http://${ip}/resetcache`);
        return response;

    }catch (e) {

        return {status: 'failure', reason: 'e.message'};
    }

}

0

मैंने इसे सिंक किए बिना ऐसा करने का एक तरीका (वर्कअराउंड) पाया है।

तो जैसा कि पहले उल्लेख किया गया था कि Promise.allकोई भी नहीं है।

इसलिए ... समाधान को पकड़ने और बल देने के लिए एक संलग्न वादे का उपयोग करें।


      let safePromises = originalPrmises.map((imageObject) => {
            return new Promise((resolve) => {
              // Do something error friendly
              promise.then(_res => resolve(res)).catch(_err => resolve(err))
            })
        })
    })

    // safe
    return Promise.all(safePromises)

0

आपको यह जानना होगा कि अपने परिणामों में त्रुटि की पहचान कैसे करें। यदि आपके पास एक मानक अपेक्षित त्रुटि नहीं है, तो मेरा सुझाव है कि आप कैच ब्लॉक में प्रत्येक त्रुटि पर एक परिवर्तन चलाते हैं जो इसे आपके परिणामों में पहचानने योग्य बनाता है।

try {
  let resArray = await Promise.all(
    state.routes.map(route => route.handler.promiseHandler().catch(e => e))
  );

  // in catch(e => e) you can transform your error to a type or object
  // that makes it easier for you to identify whats an error in resArray
  // e.g. if you expect your err objects to have e.type, you can filter
  // all errors in the array eg
  // let errResponse = resArray.filter(d => d && d.type === '<expected type>')
  // let notNullResponse = resArray.filter(d => d)

  } catch (err) {
    // code related errors
  }

0

लॉग करने में त्रुटि का सबसे अच्छा तरीका नहीं है, लेकिन आप हमेशा वादे के लिए सब कुछ एक सरणी में सेट कर सकते हैं, और परिणामी परिणामों को नए चर में संग्रहीत कर सकते हैं।

यदि आप ग्राफकॉक का उपयोग करते हैं, तो आपको प्रतिक्रिया की परवाह किए बिना प्रतिक्रिया करने की आवश्यकता है और यदि यह सही संदर्भ नहीं पाता है, तो यह एप्लिकेशन को क्रैश कर देगा, जहां समस्या कम है

const results = await Promise.all([
  this.props.client.query({
    query: GET_SPECIAL_DATES,
  }),
  this.props.client.query({
    query: GET_SPECIAL_DATE_TYPES,
  }),
  this.props.client.query({
    query: GET_ORDER_DATES,
  }),
]).catch(e=>console.log(e,"error"));
const specialDates = results[0].data.specialDates;
const specialDateTypes = results[1].data.specialDateTypes;
const orderDates = results[2].data.orders;

-1

यह कैसे Promise.allकाम करने के लिए डिज़ाइन किया गया है। यदि एक भी वादा किया जाता है reject(), तो पूरी विधि तुरंत विफल हो जाती है।

ऐसे मामलों का उपयोग किया जाता है जहां कोई व्यक्ति Promise.allवादों को विफल करने की अनुमति देना चाहता है । ऐसा करने के लिए, बस reject()अपने वादे में किसी भी बयान का उपयोग न करें । हालाँकि, यह सुनिश्चित करने के लिए कि आपका ऐप / स्क्रिप्ट किसी भी अंतर्निहित वादे के जवाब में कभी फ्रीज नहीं होता है, आपको इस पर एक समय सीमा लगाने की जरूरत है।

function getThing(uid,branch){
    return new Promise(function (resolve, reject) {
        xhr.get().then(function(res) {
            if (res) {
                resolve(res);
            } 
            else {
                resolve(null);
            }
            setTimeout(function(){reject('timeout')},10000)
        }).catch(function(error) {
            resolve(null);
        });
    });
}


reject()अपने वादे का उपयोग नहीं करना ठीक है, लेकिन अगर आपको किसी अन्य पुस्तकालय के वादों का उपयोग करने की आवश्यकता है तो क्या होगा?
डैन डस्केल्सस्कु

-8

मैंने इस समस्या से और अधिक सुंदर से निपटने के लिए एक एनपीएम लाइब्रेरी लिखी। https://github.com/wenshin/promiseallend

इंस्टॉल

npm i --save promiseallend

2017-02-25 नए एपीआई, यह वादा सिद्धांतों को तोड़ नहीं है

const promiseAllEnd = require('promiseallend');

const promises = [Promise.resolve(1), Promise.reject('error'), Promise.resolve(2)];
const promisesObj = {k1: Promise.resolve(1), k2: Promise.reject('error'), k3: Promise.resolve(2)};

// input promises with array
promiseAllEnd(promises, {
    unhandledRejection(error, index) {
        // error is the original error which is 'error'.
        // index is the index of array, it's a number.
        console.log(error, index);
    }
})
    // will call, data is `[1, undefined, 2]`
    .then(data => console.log(data))
    // won't call
    .catch(error => console.log(error.detail))

// input promises with object
promiseAllEnd(promisesObj, {
    unhandledRejection(error, prop) {
        // error is the original error.
        // key is the property of object.
        console.log(error, prop);
    }
})
    // will call, data is `{k1: 1, k3: 2}`
    .then(data => console.log(data))
    // won't call
    .catch(error => console.log(error.detail))

// the same to `Promise.all`
promiseAllEnd(promises, {requireConfig: true})
    // will call, `error.detail` is 'error', `error.key` is number 1.
    .catch(error => console.log(error.detail))

// requireConfig is Array
promiseAllEnd(promises, {requireConfig: [false, true, false]})
    // won't call
    .then(data => console.log(data))
    // will call, `error.detail` is 'error', `error.key` is number 1.
    .catch(error => console.log(error.detail))

// requireConfig is Array
promiseAllEnd(promises, {requireConfig: [true, false, false]})
    // will call, data is `[1, undefined, 2]`.
    .then(data => console.log(data))
    // won't call
    .catch(error => console.log(error.detail))

--------------------------------

पुरानी खराब आपी, इसका उपयोग न करें!

let promiseAllEnd = require('promiseallend');

// input promises with array
promiseAllEnd([Promise.resolve(1), Promise.reject('error'), Promise.resolve(2)])
    .then(data => console.log(data)) // [1, undefined, 2]
    .catch(error => console.log(error.errorsByKey)) // {1: 'error'}

// input promises with object
promiseAllEnd({k1: Promise.resolve(1), k2: Promise.reject('error'), k3: Promise.resolve(2)})
    .then(data => console.log(data)) // {k1: 1, k3: 2}
    .catch(error => console.log(error.errorsByKey)) // {k2: 'error'}

यह कैसे काम करता है? कृपया फ़ंक्शन के अपने कार्यान्वयन को दिखाएं और समझाएं।
बरगी

मैंने जैसे एक नया समवर्ती तर्क लिखा Promise.all। लेकिन यह हर वादे के सभी डेटा और त्रुटियों को एकत्रित करेगा। यह भी वस्तु इनपुट का समर्थन करता है, यह बात नहीं है। सभी डेटा और त्रुटियों को एकत्र करने के बाद, मैं promise.thenपंजीकृत कॉलबैक से निपटने के लिए विधि को ओवरराइड करता हूं जिसमें अस्वीकृत और पूर्ण शामिल हैं। विस्तार के लिए आप कोड
wenshin

उह, उस कोड को दोनों onFulfilledऔर onRejectedहैंडलर कहा जाएगा जो पास हो गए हैं then?
बर्गी १

हाँ, केवल जब वादा स्थिति मिक्स fulfilledऔर rejected। लेकिन वास्तव में यह एक कठिन समस्या का कारण बनता है सभी वादे के साथ संगत मामलों का सामान्य रूप से, जैसे onFulfilledऔर onRejectedसभी वापसी Promise.reject()या Promise.resolve()। अब तक मैं स्पष्ट नहीं हूं कि इसे कैसे हल किया जाए, क्या किसी के पास बेहतर विचार है? अब के लिए सबसे अच्छा जवाब एक समस्या है, यह ब्राउज़र वातावरण में डेटा और त्रुटियों को फ़िल्टर नहीं कर सकता है।
वेन्शिन

क्या हमें पाइप अजगर पैकेज मैनेजर के साथ एनपीएम मॉड्यूल स्थापित करने की आवश्यकता है?
सातफूर्क
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.