web-dev-qa-db-ja.com

setTimeout内で解決を約束するために複数の引数を渡す

MDN promise.all の例に沿って実行しようとしましたが、 setTimeoutコールバック にこれ以上引数を渡すことができないようです。

var p1 = new Promise((resolve, reject) => { 
  setTimeout(resolve, 200, 1,2,3); 
});
var p2 = new Promise((resolve, reject) => { 
  setTimeout(resolve, 500, "two"); 
});

Promise.all([p1, p2]).then(value => { 
  console.log(value);
}, reason => {
  console.log(reason)
});

これは[1, "two"]を出力しますが、ここで[1, 2, 3, "two"]を期待します。約束の履行なしにsetTimeoutでこれを行うと、期待どおりに機能します

setTimeout(cb, 100, 1, 2, 3);
function cb(a, b, c){
  console.log(a, b, c);
}
//=>1 2 3

なぜこれは約束で機能しないのですか?どうすれば約束を果たすことができますか?

11
1252748

resolve関数は1つの引数のみを取ります。これは仕様なので、変更することはできません。

それ以上渡しても違いはなく、他の値は無視されます。

配列をresolve関数に渡すことを選択できますが、配列はthenハンドラーで取得され、必要な独立した値ではありません。

12
Amit

resolve()は1つの引数のみを受け入れて処理し、履行されたpromiseには1つの値しかありません。これはpromise仕様によるものであり、変更できるものではありません。

複数の情報を渡したい場合は、複数のデータを配列またはオブジェクトにラップし、その1つのオブジェクトを解決された値として使用してから、受信コードを変更して、ラップされたオブジェクトでアクセスできるようにします。

_var p1 = new Promise((resolve, reject) => { 
  // put multiple resolved values into an array
  setTimeout(resolve, 200, [1,2,3]), 200); 
});
var p2 = new Promise((resolve, reject) => { 
  setTimeout(resolve, 500, "two"); 
});

Promise.all([p1, p2]).then(value => { 
  console.log(value);   // [[1,2,3], "two"]
}, reason => {
  console.log(reason)
});
_

配列が埋め込まれていない最終的な.then()ハンドラー内に独立した値が本当に必要な場合は、処理する前に.then()ハンドラーのvalue配列をフラット化できます。結果。配列をフラット化するための多くのテクニックがここにあります: JavaScriptで配列の配列をマージ/フラット化しますか?

6
jfriend00