247

ドキュメントはそれについてあまり明確ではないので、この点を明確にしたいと思います。

Q1:すべてのプロミスはPromise.all(iterable)順次処理されますか、それとも並列処理されますか? または、より具体的には、チェーンされたプロミスのような実行と同等ですか

p1.then(p2).then(p3).then(p4).then(p5)....

または、すべてが同時に(並行して)呼び出され、すべてが解決(または拒否)されるとすぐに結果が返される、他p1の種類のアルゴリズムですか?p2p3p4p5

Q2:並列で実行する場合Promise.all、イテラブルを順次実行する便利な方法はありますか?

: Q や Bluebird は使用したくありませんが、すべてのネイティブ ES6 仕様を使用します。

4

14 に答える 14

334

Promise.all(iterable)すべての約束を実行していますか?

いいえ、約束は「実行」できません。それらは作成時にタスクを開始します- それらは結果のみを表します- そして、それらを に渡す前であっても、すべてを並行して実行していPromise.allます。

Promise.all複数の約束を待つだけです。それらが解決される順序や、計算が並行して実行されているかどうかは気にしません。

イテラブルを順次実行する便利な方法はありますか?

すでに約束をしている場合は、多くのことはできませんがPromise.all([p1, p2, p3, …])(これには順序の概念がありません)。しかし、反復可能な非同期関数がある場合は、それらを順番に実行できます。基本的にあなたはから得る必要があります

[fn1, fn2, fn3, …]

fn1().then(fn2).then(fn3).then(…)

それを行うための解決策は次を使用することですArray::reduce

iterable.reduce((p, fn) => p.then(fn), Promise.resolve())
于 2015-06-13T21:28:23.347 に答える
5

@Bergi答えを詳しく説明するだけです(これは非常に簡潔ですが、理解するのは難しいです;)

このコードは、配列内の各アイテムを実行し、次の「then chain」を最後に追加します。

function eachorder(prev,order) {
        return prev.then(function() {
          return get_order(order)
            .then(check_order)
            .then(update_order);
        });
    }
orderArray.reduce(eachorder,Promise.resolve());
于 2016-09-08T13:58:04.810 に答える
4

async awaitを使用すると、promiseの配列を順番に簡単に実行できます。

let a = [promise1, promise2, promise3];

async function func() {
  for(let i=0; i<a.length; i++){
    await a[i]();
  }  
}

func();

注: 上記の実装では、promise が拒否された場合、残りは実行されません。すべての promise を実行する場合は、await a[i]();内部をラップします。try catch

于 2019-06-22T07:42:56.343 に答える
2

forループでできます。

非同期関数の戻り値の約束:

async function createClient(client) {
    return await Client.create(client);
}

let clients = [client1, client2, client3];

次のコードを記述すると、クライアントが並行して作成されます。

const createdClientsArray = yield Promise.all(clients.map((client) =>
    createClient(client);
));

ただし、クライアントを順番に作成する場合は、for ループを使用する必要があります。

const createdClientsArray = [];
for(let i = 0; i < clients.length; i++) {
    const createdClient = yield createClient(clients[i]);
    createdClientsArray.push(createdClient);
}
于 2016-02-25T11:36:27.360 に答える
0

はい、次のように promise を返す関数の配列をチェーンできます (これにより、各関数の結果が次の関数に渡されます)。もちろん、それを編集して、各関数に同じ引数 (または引数なし) を渡すこともできます。

function tester1(a) {
  return new Promise(function(done) {
    setTimeout(function() {
      done(a + 1);
    }, 1000);
  })
}

function tester2(a) {
  return new Promise(function(done) {
    setTimeout(function() {
      done(a * 5);
    }, 1000);
  })
}

function promise_chain(args, list, results) {

  return new Promise(function(done, errs) {
    var fn = list.shift();
    if (results === undefined) results = [];
    if (typeof fn === 'function') {
      fn(args).then(function(result) {
        results.push(result);
        console.log(result);
        promise_chain(result, list, results).then(done);
      }, errs);
    } else {
      done(results);
    }

  });
}

promise_chain(0, [tester1, tester2, tester1, tester2, tester2]).then(console.log.bind(console), console.error.bind(console));

于 2018-01-29T10:27:26.743 に答える