2017-02-23 6 views
0

アイテムの配列に対していくつかの約束をする必要がありますが、配列の長さはわかりません。これらの約束をどのようにして順番に実行するのですか?これは私が非同期で行う方法です:シーケンスの約束をどのように実行するのですか

const arrayABC = [a, b, c.....x, y, z] // length unknown 
const promises = arrayABC.map(function(item) { 
    doSomething(item) 
    } 
return Promise.all(promises) 

私はそれらを1つずつ実行する必要があります。

+0

Aが不要オプションで、ちょうどあなたがArray#mapのためにそれを使用する方法のように動作し、Array#forEach重複(?)http://stackoverflow.com/a/21372335/251311 – zerkms

+0

この質問はここで徹底的に答えられました。もう少し調べてください。 –

答えて

1

私が正しくあなたのセットアップを理解すると仮定すると、これが最も合理的なアプローチを思わ:

// return the promise chain from last element 
return arrayABC.reduce(function (chain, item) { 
    // bind item to first argument of function handle, replace `null` context as necessary 
    return chain.then(doSomething.bind(null, item)); 
// start chain with promise of first item 
}, doSomething(arrayABC.shift())); 
+2

同じ式で変異した配列を減らすことは醜いです。代わりに初期値としてダミー解決済みの約束を渡すかもしれません。 – zerkms

+0

イベントループを無駄にする@zerkms –

+2

イベントループの反復と議論の的になるコード...:-S – zerkms

-1

あなたのコードが非同期並列いる間に次のマッピングは、非同期シーケンシャルです。

function sequentialAsyncMap(array, fn) { 
 
    var p = Promise.resolve(); 
 
    return Promise.all(array.map(
 
     (item, index, collection) => p = p.then(
 
      () => fn(item, index, collection) 
 
     ) 
 
    )); 
 
} 
 

 
function delay(timeout, value) { 
 
    return new Promise(resolve => { 
 
     setTimeout(() => resolve(value), timeout); 
 
    }); 
 
} 
 

 
sequentialAsyncMap([1, 2, 3], i => { 
 
    console.log(i); 
 
    return delay(500, 2*i); 
 
}).then(result => { 
 
    console.log(result); 
 
});

0

あなたは青い鳥使用してダウンしている場合 - http://bluebirdjs.com/docs/api/promise.each.htmlを - あなたは順番に実行するために.each()を使用することができます。あなたはすべての約束の結果(あなたがPromise.allでできるような)にアクセスする必要がある場合は文書から取られた例が

const Promise = require('bluebird') 

let queue = []; 

queue.push(function() { 
    return new Promise(function(resolve, reject) { 
    // Some asynchronous task. 
    console.log("Processing item 1..."); 
    setTimeout(resolve, 3000); 
    }); 
}); 

queue.push(function() { 
    return new Promise(function(resolve, reject) { 
    // Some asynchronous task. 
    console.log("Processing item 2..."); 
    setTimeout(resolve, 1000); 
    }); 
}); 

Promise.each(queue, function(queue_item) { 
    // *Now* we call the function. Since it returns a promise, the next iteration will not run until it resolves. 
    return queue_item(); 
}); 
-1

コメント - 次の操作を実行できます。

Promise.series = (array, fn, thisArg) => { 
    var p = Promise.resolve(); 
    return Promise.all(Array.from(array).map((...args) => 
     p = p 
     .then(() => fn.apply(thisArg, args)) 
    )); 
}; 

次に、あなたのコードは

なり、
const arrayABC = [a, b, c.....x, y, z] // length unknown 
return Promise.series(promises, doSomething); 

(この場合doSomethingで)コールバックは、ちょうどArray#mapのように、引数item, index, arrayが渡されますなど

thisArgなど

代替Promise.series

Promise.series = (array, fn, thisArg) => 
    Array.from(array).reduce((promise, ...args) => 
     promise 
     .then(results => 
      fn.apply(thisArg, args) 
      .then(result => results.concat(result)) 
     ), Promise.resolve([]) 
    ); 

同じ結果が、Promise.all

関連する問題