2017-11-17 1 views
1

promise.all()を使用してループの後に関数のリストを同期して実行しようとしていますが、コードが期待通りに機能しません。ノードpromises.all()が正常に動作しません

誰かが私が間違っていたことを知っていますか?

私のコードは次のとおりです。私は

push promise 0 
push promise 1 
push promise 2 
---> foo i 0 
---> foo i 1 
---> foo i 2 
done 

を期待するところ

var Promise = require('promise'); 
var promises = []; 

for (var i = 0; i < 3; i++) { 
    console.log('push promise ' + i); 
    promises.push(foo(i)); 
} 

Promise.all(promises) 
     .then(function (data) { 
      console.log("done"); 
     }); 

function foo(i) { 
    return new Promise(function (resolve, reject) { 
     console.log('---> foo i ' + i); 
     resolve('done foo ' + i); 

    }); 
} 

が、出力は

push promise 0 
---> foo i 0 
push promise 1 
---> foo i 1 
push promise 2 
---> foo i 2 
done 

で事前にありがとうございます。

+1

すべての約束は、作成されたときの解決を開始します。 'Promise.all'を呼び出すと、引数がすべて解決されたときに解決する別の約束事が作成されます。コンストラクタ関数には非同期動作がないことに注意してください。 [setTimeout(...、0)](https://stackoverflow.com/questions/1360238/myfunction-vs-window-settimeoutmyfunction-0)を使用して、期待する実行順序を達成することができます。 – allonhadaya

答えて

2

を与えるべきではあなたが約束コンストラクタを呼び出すときに、それに渡される関数は、建設通話中に呼び出されていることです。 プロキシの内部に非同期呼び出しがある場合(意図したユースケース)、期待していた動作が作成されます。

私のコード例は、setTimeoutを非同期呼び出しとして使用し、resolve呼び出しが非同期コールバック内でどのように行われるかに注意してください。

var promises = []; 

for (var i = 0; i < 3; i++) { 
    console.log('push promise ' + i); 
    promises.push(foo(i)); 
} 

Promise.all(promises) 
     .then(function (data) { 
      console.log("done"); 
     }); 

function foo(i) { 
    return new Promise(function (resolve, reject) { 
     // The async call is made inside the Promise 
     setTimeout(()=> { 
      console.log('---> foo i ' + i); 
      // And the resolve call is made inside the callback function 
      resolve('done foo ' + i); 
     }); 
    }); 
} 

これを実行すると、あなたは所望の出力(クロームでテスト)を取得する必要があります

push promise 0 
push promise 1 
push promise 2 
---> foo i 0 
---> foo i 1 
---> foo i 2 
done 

追記:こののみ動作(foo i 0, ... 1 ... 2が順になっている)要求は全て即座に行われているので1つずつそれがajax呼び出しだった場合、fooステートメントは完了の順に表示されます。したがって、要求2が0または1より前に終了した場合、最初にfoo i 2が表示されます。しかし、は、すべての要求が解決された場合にのみ表示されます。

-1

resolveメソッドの外にあり、代わりにPromiseコンストラクタに指定したエグゼキュータ関数の中に、console.log('---> foo i ' + i);という行が約束されて実行されています。

これは、ここで何が起こっている、あなたの期待出力

var Promise = require('promise'); 
var promises = []; 

for (var i = 0; i < 3; i++) { 
    console.log('push promise ' + i); 
    promises.push(foo(i)); 
} 

Promise.all(promises) 
     .then(function (data) { 
      for (var i = 0; i < data.length; i++) { 
      console.log(data[i]); 
      }   
      console.log("done"); 
     }); 

function foo(i) { 
    return new Promise(function (resolve, reject) { 
     resolve('--> foo i ' + i); 
    }); 
} 
+0

'resolve'コールバックの外にありますか? 'resolve'コールバックはありません。 –

+0

彼はおそらくExecutor関数が 'Promise'コンストラクタに渡されることを意味します。 – rossipedia

+0

正しく、私は間違った用語を使用しました。金曜日の午後遅く、申し訳ありません。私はそれを解決します。 –

0

私はpromise.all()を使用してループの後に関数のリストを同期して実行しようとしていますが、コードが期待通りに機能しません。

あなたは機能のリストを同期して実行したいと思います。その場合は、Bluebird Promise.each()を使用することをお勧めします。

var Promise = require('bluebird'); 
var promises = []; 

for (var i = 0; i < 3; i++) { 
    console.log('push promise ' + i); 
    promises.push(foo(i)); 
} 

Promise.each(promises, function(result) { 
    console.log(result); 
}); 

function foo(i) { 
    return new Promise(function (resolve, reject) { 
     resolve('done foo ' + i); 
    }); 
} 

結果:

push promise 0 
push promise 1 
push promise 2 
done foo 0 
done foo 1 
done foo 2 
関連する問題