2017-03-29 7 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を実行し、次の繰り返しを続ける前に約束が解決されるのを待ちますか?

+1

Promise.Allはそれが十分ではありません、あなたは独自のオン –

+1

@JohnPetersたいものがあるからそれは順番に解決されません。 – 4castle

答えて

15

あなたは倍に.thenの繰り返し適用を行うことができます。

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

ブルーバード、あなたが使用する必要があります優れた約束ライブラリあなたがいない場合、またhas mapSeries built in

Promise.mapSeries(myArray, myPromise) 

Runnableをスニペット:

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(results => fn(x).then(r => results.concat )、)Promise.resolve([]))then then(results => {}); –

0

私はbabelを使用し、それをこのようにします:あなたはArray.reduceを使用することができ

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

私はあなたの2番目の例が逐次実行されるとは限りません。 –

1

。もちろん

//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

あなたは要素の配列を反復し、このようなのparamsを渡すことができます。

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)) 
 
);

関連する問題