2015-02-23 5 views
16

मेरे पास एक लाइब्रेरी से एक फ़ंक्शन है जो एक वादा करता है। मुझे इस समारोह को कई बार चलाने की ज़रूरत है, लेकिन प्रत्येक पुनरावृत्ति को पिछले कार्य तक पूरा होने तक प्रतीक्षा करनी चाहिए।आप es6 वादों की एक श्रृंखला को कैसे सिंक्रनाइज़ करते हैं?

मेरे धारणा मैं यह कर सकता है कि था:

promiseReturner(1) 
    .then(promiseReturner(2) 
    .then(promiseReturner(3) 
    .then(...) 

कौन सा एक पाश का उपयोग कर सरल किया जा सकता है:,

var p = Promise.resolve(); 
for (var i=1; i<=10; i++) { 
    p = p.then(promiseReturner(i)); 
} 

लेकिन जब मैं इस श्रृंखला में प्रत्येक वादा पर निष्पादित किया जाता है कर एक ही समय के बाद, .then() के रूप में दूसरे के बजाय एक का मतलब है। जाहिर है, मुझे वादे के बारे में कुछ मौलिक याद आ रहा है - लेकिन कई ट्यूटोरियल और ब्लॉग पोस्ट पढ़ने के बाद भी मैं हार गया हूं।

Here's a codepen I wrote up to demonstrate my attempt

+1

करता है 'promiseReturner (एन) 'एक वादा वापस करें या एक वादा-वापसी समारोह बनाओ? – Bergi

उत्तर

21

आपका "गैर-लूप" समाधान या तो काम नहीं करना चाहिए। तुम्हें पता है, नहीं एक वादा.then करने के लिए एक समारोह पारित करने के लिए है: कि समारोह एक वादा रिटर्न

var p = Promise.resolve(); 
for (var i=1; i<=10; i++) { 
    (function(i) { 
     p = p.then(function() { 
      return promiseReturner(i); 
     }); 
    }(i)); 
} 

है, तो आप उस चेनिंग प्रभाव मिलता है।

MDN पर वादों के बारे में अधिक जानकारी।


let (और तीर कार्यों) के साथ सरल किया जा सकता है:

var p = Promise.resolve(); 
for (let i=1; i<=10; i++) { 
    p = p.then(() => promiseReturner(i)); 
} 

या .bind (जो ES5 है):

var p = Promise.resolve(); 
for (var i=1; i<=10; i++) { 
    p = p.then(promiseReturner.bind(null, i)); 
} 
+2

शायद अधिक स्पष्ट: "आपको एक समारोह * पास करना होगा * एक वादा * *? –

+0

कभी भी आपको यह समझाने में कोई फर्क नहीं पड़ता कि बाद में –

+0

पर मैंने इसे पहले एक समारोह में लपेटने की कोशिश की थी [यहां देखें] (http://codepen.io/anon/pen/zxjExL?editors=001), लेकिन यह केवल अंतिम भागना प्रतीत होता था पक्का वादा।एक स्व-चालान समारोह में इसे अवरुद्ध करने वाले रैपिंग को ठीक करने के लिए क्यों लगता है? –

1

आप ES6 जनरेटर और एक पुस्तकालय का उपयोग कर async/await उपयोग कर सकते हैं co की तरह।

var recursiveFunction = function(values) { 
    return new Promise(function(resolve, reject) { 
    if (values.length <= 0) { 
     return resolve(); 
    } else { 
     return promiseReturner(values[0]).then(function() { 
      values.shift(); 
      return recursiveFunction(values).then(function() { 
       resolve(); 
      }); 
     }); 
     } 
    }); 
} 

recursiveFunction([1,2]).then(function(r) { 
console.warn('Finished solving promises sequentially'); 
}) 
1

यहाँ एक समाधान है जो मैं एक ही समस्या का समाधान करने के लिए इस्तेमाल है:

co(function*() { 
    while(upto < 10) { 
    var result = yield Promise.resolve(true); 
    } 
    return result; 
}).then(function (value) { 
    console.log(value); 
}, function (err) { 
    console.error(err.stack); 
}); 

यहाँ कुछ विस्तार यह इस तरह होता । मुझे काफी अच्छी तरह से लगता है।

const functions = [/* array of functions which return promises */]; 
const finalPromise = functions.reduce(async (promise, asyncFn) => { 
    await promise; 
    return asyncFn(); 
}, Promise.resolve()); 
-1

आप nsynjs के माध्यम से अपने कोड चला सकते हैं, यह निष्पादन प्रत्येक कार्य उस वादे को रिटर्न पर रोक देगा, और जब तक वादा हल हो गई है इंतजार करेंगे:

var promiseReturner = function(i) { 
 
    return new Promise(function(resolve, reject) { 
 
     setTimeout(function(){ 
 
      resolve("result is "+i) 
 
     }, 1000); 
 
    }); 
 
}; 
 

 
function synchronousCode() { 
 
    for (var i=1; i<=10; i++) { 
 
     var p=promiseReturner(i); // nsynjs will pause here until promise is resolved 
 
     console.log(p.data); // `data` will contain result of the promise 
 
    } 
 
}; 
 
\t 
 
nsynjs.run(synchronousCode, null, function(){ 
 
\t console.log("finish"); 
 
});
<script src="https://rawgit.com/amaksr/nsynjs/master/nsynjs.js"></script>

संबंधित मुद्दे