2017-03-29 10 views
5
var myArray = [1, 2, 3, 4, 5, 6] 

function myPrommise(num){ 
    return new Promise(res => { 
    window.setTimeout(()=>{ 
     res( console.log("done: " + num) ) 
    },2000) 
    }) 
} 


myPrommise(myArray[0]) 
    .then(x => myPrommise(myArray[1])) 
    .then(x => myPrommise(myArray[2])) 
    .then(x => myPrommise(myArray[3])) 
    .then(x => myPrommise(myArray[4])) 
    .then(x => myPrommise(myArray[5])) 

अभी, यदि मैं ऊपर दिए गए कथन को निष्पादित करता हूं, तो यह अनुक्रमिक रूप से चलाएगा। मेरे वास्तविक उपयोग मामले में सरणी गतिशील रूप से आबादी है और मुझे myArray में प्रत्येक सदस्य के लिए myPromise() फ़ंक्शन निष्पादित करने की आवश्यकता है।अनुक्रमिक रूप से वादे निष्पादित करने के लिए, सरणी से पैरामीटर को पारित करना?

मैं "पॉज़ेबल लूप" कैसे बना सकता हूं जो सरणी में प्रत्येक आइटम के लिए लूप करेगा, myPromise निष्पादित करेगा और अगली पुनरावृत्ति जारी रखने से पहले वादा को हल करने का इंतजार करेगा?

myArray.reduce(
    (p, x) => 
    p.then(_ => myPromise(x)), 
    Promise.resolve() 
) 

Bluebird, एक उत्कृष्ट वादा पुस्तकालय आप का उपयोग करना चाहिए यदि आप नहीं कर रहे हैं, यह भी has mapSeries built in:

Promise.mapSeries(myArray, myPromise) 

Runnable

+1

Promise.All क्या आप –

+1

@JohnPeters अपने स्वयं पर चाहते है, कि, पर्याप्त नहीं है क्योंकि यह अनुक्रमिक रूप से हल नहीं होगा। – 4castle

उत्तर

15

आप एक गुना में .then के बार-बार आवेदन कर सकते हैं स्निपेट:

const myArray = [1, 2, 3, 4, 5, 6] 
 

 
const sleep = ms => 
 
    new Promise(res => { 
 
    setTimeout(res, ms) 
 
    }) 
 

 
const myPromise = num => 
 
    sleep(500).then(() => { 
 
    console.log('done: ' + num) 
 
    }) 
 

 
myArray.reduce(
 
    (p, x) => 
 
    p.then(_ => myPromise(x)), 
 
    Promise.resolve() 
 
)

+1

यदि आपको 'Promise.all' - 'myArray.reduce ((p, x) => p.then (परिणाम => fn (x) .then (r => results.concat (r) के साथ लौटाए गए सभी परिणामों की आवश्यकता है))), Promise.resolve ([]))। फिर (परिणाम => {}); ' –

0

मैं babel का उपयोग करें और यह इस तरह से करना होगा:

let args = [1, 2, 3]; 
 
    
 
    const myPromise = async x => console.log('arg:',x); 
 
    
 
    const test = async() => { 
 
     for (let task of args.map(myPromise)) 
 
     await task; 
 
    } 
 
    
 
    test().then(console.log('Done'));
<script src="https://unpkg.com/[email protected]/babel.min.js"></script>

+1

मेरा मानना ​​है कि आपका दूसरा उदाहरण अनुक्रमिक रूप से चलाने की गारंटी नहीं है। –

1

आप Array.reduce इस्तेमाल कर सकते हैं।

//type: [number] 
var myArray = [1, 2, 3, 4, 5, 6] //doesn't really matter 

//type: number -> Promise<number> 
function myPromise(num){ 
    return new Promise((resolve) => { 
    window.setTimeout(()=>{ 
     resolve(console.log("done: " + num) ) 
    },2000) 
    }) 
} 

//Array.reduce has type: [a] ~> ((b, a) -> b), b) -> b 
//So it can have type: 
//[number] ~> ((Promise<number> -> number -> Promise<number>), Promise<number>) -> Promise<number> 
//Therefore we need to give reduce a function that takes a Promise 
//resolving to a number and a number which makes a new promise. 
//This is the function we want: 

function sequencePromises(promise, number) { 
    return new Promise((resolve) => { 
    resolve(promise.then(_ => myPromise(number))); 
    } 
} 

myArray.reduce(sequencePromises, Promise.resolve()); 
बेशक

, यदि आप एक वादा जो त्रुटि सकते हैं या आप चाहते हो सकता है अगर आप पिछले परिणामों की जरूरत है, ताकि बनाने के लिए sequencePromises अधिक सामान्य है इस साधारण दृष्टिकोण से काम नहीं चलेगा:

function genericSequencePromises(promiseFunction) { 
    return (promise, parameter) => { 
    return new Promise((resolve, reject) => 
         return promiseFunction(resolve, 
               reject, 
               promise, 
               parameter)); 
    } 
} 

फिर जब तक आप वादा वापस कर लेते हैं तब तक आप जो भी चाहें कर सकते हैं। यह सब एक साथ लाने

function promiseSeries(array, reducer) { 
    return array.reduce(reducer, Promise.resolve()); 
} 

:

अंत में, आप इस छोटे सहायक से लाभ हो सकता

let sequencePromises = genericSequencePromises((resolve, reject, promise, num) => { 
    resolve(promise.then(_ => console.log(`done: ${num}`))); 
} 

promiseSeries(myArray, sequencePromises); 

इस तरह, आप केवल अपने प्रश्न में मामले को संभाल नहीं सकते हैं, लेकिन और अधिक जटिल मामले

0

आप तत्वों की सरणी पर पुनरावृति और इस तरह पैरामीटर पारित कर सकते हैं:

const arr = [1, 2, 3, 4, 5, 6]; 
 
const MyPromiseFunction = num => new Promise((resolve, reject) => { 
 
    // Your logic... 
 
    setTimeout(() => num <= 4 
 
    ? resolve('Success!') 
 
    : reject('Rejected!'), 1000 * num); 
 
}); 
 
const logMessage = (num, msg) => console.log(`For number ${num} promise result: ${msg}`); 
 

 
arr.forEach(
 
    num => MyPromiseFunction(num) 
 
    .then(message => logMessage(num, message)) 
 
    .catch(reason => logMessage(num, reason)) 
 
);

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