2016-05-06 28 views
0

私は実行する必要がある関数の配列を持っています。 これらの関数はすべて約束を返します。約束が成立した後に約束を返す実行関数

すべての関数を直列に実行したいが、次の関数は、前の関数の約束が完了している場合にのみ開始することができます。

これはasyncまたはbluebirdライブラリでは簡単だと思っていましたが、これに対して簡単な解決策が見つかりません。

これは私が(テストされていない)ものですが、これは既に存在するため、標準のライブラリソリューションを探していましたか?

function runFuncs(funcs) { 

    function funcRunner(funcs, resolve, reject, pos=0) { 
     funcs[pos]().then(function() { 
      pos++; 
      if (pos < length(funcs)) { 
       funcRunner(funcs, pos); 
      } else { 
       resolve(); 
      } 
     }).catch(function(err) { 
      reject(err); 
     }); 
    } 

    return new Promise(function(resolve, reject) { 
     funcRunner(funcs, resolve, reject); 
    }); 
} 
+0

を、あなたは '含めることができますあなたは質問で試したことがありますか?そして、期待されたものと実際の結果が何であるかを記述する。 – guest271314

+0

^^^^あなたを助けるためにいくつかのコードが必要です。 @ guest271314は何を言った –

+0

@ r03 _ "私は(テストされていない)ものを作りましたが、標準のライブラリソリューションを探していました。 Questionで 'js'と似たパターンを使用するライブラリの勧告を求めていますか? Questionに 'funcs'配列に含まれる' js'を含めることができますか? – guest271314

答えて

1

私はすでに答えをマークしていますが、まだコメントすることはできず、質問する必要があります。あなたの例は、ある関数の結果を別の関数に渡すようには見えません。 ?

シリーズが厳しい条件の場合、Bluebirdの.mapSeries()メソッドは、あなたが探しているものを正確に行い、コードは信じられないほどきれいです。それ以外の場合は、.map()に入れ替えて並行性を活用して、並行処理を行うことができます。

Promise.mapSeries(fnArray, (fn) => 
{ 
    return fn(...); 
}) 
.then((results) => 
{ 
    // do something with the results. 
}); 

それとも.map()と並行して:

Promise.map(fnArray, (fn) => 
{ 
    return fn(...); 
}, 
{ concurrency: 5 }) 
.then((results) => 
{ 
    // do something with the results. 
}); 
+0

はい、次の機能は、前の約束が完了したばかり(開始されたばかりではない)に開始されることがあります。明確化のために – r03

+0

ありがとうございます。 '.mapSeries'はライブラリーを使うのが良い方法です。 –

4

各関数が約束を返す場合は、それらを連鎖させることができます。このようなものはうまくいくはずです:

基本的には、約束をまとめておきます。チェーンの性質上、thenハンドラから約束を返せば、それは結果として得られる約束になります。したがって、reduce呼び出しは配列内の次のものを処理するためにthenを実行して、配列内の各約束を処理します。

+0

これは私よりもはるかに良い答えです。:) – lanceball

0

私は簡単な古いJSコードだけを追加ライブラリを使用せずに簡単な解決策を考え出すことができました。この例では

'use strict'; 

// Create an array of functions that return a promise 
const promises = []; 
let i = 0; 
while (i++ < 10) { 
    const v = i; 
    promises.push(() => { 
    return new Promise((resolve, reject) => { 
     setTimeout(() => { 
     resolve(v); 
     }, Math.floor(Math.random() * 1000)); 
    }); 
    }); 
} 

function nextPromise(idx) { 
    if (idx >= promises.length) return; 
    promises[idx]().then((v) => { 
    console.log("Resolved", v); 
    nextPromise(++idx); 
    }); 
} 

nextPromise(0); 

、Iは、ミリ秒のランダムな番号の後に単調に増加する数を解決約束を返すそれぞれが10個の機能の配列を作成しました。

これらをすべて順番に実行するには、ちょうど再帰を使用します。これはハッキーに見えるコードのような醜いビットですが、うまく機能します。

0

"のfuncsは" 約束の配列である場合は、することができますPromise.all()を使用する - Promise docs

import {Promise} from 'es6-promise'; 

const runFuncs = funcs => { 
    return Promise.all(funcs); 
}; 

export default runFuncs;