Promise.all ()। तो () हल?


95

नोड 4.x का उपयोग करना। जब आपके पास Promise.all(promises).then()डेटा को हल करने और अगले को पास करने का उचित तरीका क्या है .then()?

मैं कुछ इस तरह करना चाहता हूं:

Promise.all(promises).then(function(data){
  // Do something with the data here
}).then(function(data){
  // Do more stuff here
});

लेकिन मुझे यकीन नहीं है कि डेटा को 2 में कैसे लाया जाए .then()। मैं resolve(...)पहली बार में उपयोग नहीं कर सकता .then()। मुझे लगा कि मैं यह कर सकता हूँ:

return Promise.all(promises).then(function(data){
  // Do something with the data here
  return data;
}).then(function(data){
  // Do more stuff here
});

लेकिन ऐसा करने का उचित तरीका नहीं लगता है ... इस के लिए सही तरीका क्या है?

जवाबों:


142

लेकिन ऐसा करने का उचित तरीका नहीं लगता है ..

यही कारण है कि वास्तव में यह (या कम से कम करने के लिए उचित तरीका है एक यह करने के लिए उचित तरीके से)। यह वादों का एक प्रमुख पहलू है, वे एक पाइपलाइन हैं, और डेटा को पाइपलाइन में विभिन्न हैंडलर द्वारा मालिश किया जा सकता है।

उदाहरण:

const promises = [
  new Promise(resolve => setTimeout(resolve, 0, 1)),
  new Promise(resolve => setTimeout(resolve, 0, 2))
];
Promise.all(promises)
  .then(data => {
    console.log("First handler", data);
    return data.map(entry => entry * 10);
  })
  .then(data => {
    console.log("Second handler", data);
  });

( catchहैंडलर संक्षिप्तता के लिए छोड़ दिया गया। उत्पादन कोड में, हमेशा या तो वादे का प्रचार करते हैं, या अस्वीकृति को संभालते हैं।)

हम जो आउटपुट देखते हैं, वह है:

पहला हैंडलर [1,2]
दूसरा हैंडलर [10,20]

... क्योंकि पहले हैंडलर को एक सरणी के रूप में दो वादों ( 1और 2) का संकल्प मिलता है , और फिर उन 10 में से प्रत्येक के साथ एक नया सरणी बनाता है और इसे वापस करता है। दूसरे हैंडलर को वही मिलता है जो पहले हैंडलर ने वापस किया।

यदि आप जो अतिरिक्त कार्य कर रहे हैं वह समकालिक है, तो आप इसे पहले हैंडलर में भी डाल सकते हैं :

उदाहरण:

const promises = [
  new Promise(resolve => setTimeout(resolve, 0, 1)),
  new Promise(resolve => setTimeout(resolve, 0, 2))
];
Promise.all(promises)
  .then(data => {
    console.log("Initial data", data);
    data = data.map(entry => entry * 10);
    console.log("Updated data", data);
    return data;
  });

... लेकिन अगर यह अतुल्यकालिक है तो आप ऐसा नहीं करना चाहेंगे क्योंकि यह समाप्त हो रहा है, और घोंसला जल्दी से हाथ से निकल सकता है।


1
दिलचस्प। धन्यवाद। तो क्या rejectशुरुआती Promiseसमारोह के बाद एक मूल्य के लिए संभव नहीं है ? या श्रृंखला में कहीं भी एक त्रुटि फेंकने के लिए आपको ले जाएगा .catch()? यदि ऐसा है, rejectतो पहली जगह में क्या है? सिर्फ त्रुटि क्यों नहीं? धन्यवाद फिर से,
जेक विल्सन

6
@JakeWilson: वे अलग सवाल हैं। लेकिन आप दो अलग-अलग चीजों को भ्रमित कर रहे हैं: वादा बनाना और निपटाना, और वादा संभालना । जब आप वादे का निर्माण और निपटान कर रहे हैं, तो आप उपयोग करते हैं resolveऔर reject। जब आप संभाल रहे हैं , यदि आपका प्रसंस्करण विफल रहता है, तो आप वास्तव में विफलता पथ को ट्रिगर करने के लिए एक अपवाद फेंक देते हैं। और हां, आप मूल Promiseकॉलबैक (उपयोग करने के बजाय reject) से अपवाद भी फेंक सकते हैं , लेकिन सभी विफलताएं अपवाद नहीं हैं।
टीजे क्राउडर

1

आज NodeJS नए async/awaitसिंटैक्स का समर्थन करता है । यह एक आसान वाक्यविन्यास है और जीवन को बहुत आसान बनाता है

async function process(promises) { // must be an async function
    let x = await Promise.all(promises);  // now x will be an array
    x = x.map( tmp => tmp * 10);              // proccessing the data.
}

const promises = [
   new Promise(resolve => setTimeout(resolve, 0, 1)),
   new Promise(resolve => setTimeout(resolve, 0, 2))
];

process(promises)

और अधिक जानें:


1
मैं प्रक्रिया से प्रत्येक व्यक्तिगत वादे के लिए पैरामीटर कैसे पारित कर सकता हूं? @ अमीनदव ग्लैक्सेटिन
भाव १

1

आपका return dataदृष्टिकोण सही है, यह वादा करने का एक उदाहरण है । यदि आप अपने .then()कॉलबैक से एक वादा वापस करते हैं, तो जावास्क्रिप्ट उस वादे को हल करेगा और डेटा को अगले then()कॉलबैक में पास करेगा।

बस सावधान रहें और सुनिश्चित करें कि आप त्रुटियों को संभालते हैं .catch()Promise.all()सरणी में वादों में से एक जैसे ही खारिज करता है

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