0

次のような Promise の配列があります。

let promisesArray = [
    service1.load('blabla'),
    service2.load(), // throws an errors
];

そして、それらすべてを実行して、このようなエラーをキャッチしたい

Promise.all(promisesArray)
    .then(() => doStuffs())
    .catch((err) => handleError(err));

それは正常に機能していますが、別の約束の then() でそれを行いたいと思っています:

baseService()
    .then(() => Promise.all([
        service1.load('blabla'),
        service2.load(), // throw an errors
    ]))
    .catch((err) => handleError(err));

Promise.all() に配列を直接記述している限り、これも問題なく動作しますが、promiseArraydefine を以前のように使用したい場合は、次のようにします。

baseService()
    .then(() => Promise.all(promisesArray))
    .catch((err) => handleError(err));

その後、catch()期待どおりに実行されますが、コンソールにエラーがあります

publish.js:45784 EXCEPTION: Error: Uncaught (in promise): ...

しかし、Promise をプッシュすることにより、いくつかの条件に従って配列が生成されるため、最後のソリューションを使用したいと考えています。(そして最初の例は問題なく動作していますが、何が違うのかわかりません)

配列に追加するときに各約束にキャッチを追加すると、問題は解決しますが、より良い解決策を見つけたいと思います。

私は本当にそれでいくつかの助けをいただければ幸いです.

PS:何かを変更する場合、zone.jsでangular2を使用しています

4

3 に答える 3

2

非同期関数 (promise を返す関数) を実行するとすぐに、実行した瞬間からいつでも promise が解決または拒否される可能性があるバックグラウンド (kindof) でタスクの実行が開始されます。

let promisesArray = [
    service1.load('blabla'),
    service2.load(), // throws an errors
];

これらのサービスはオフになり、データをロードします。.then() がアタッチされる前に戻った場合、値を保持し、promisesArray[0].then(x => console.log(x)) を呼び出すとすぐに値を保持します。 then 関数はその値で実行されます

ただし、これらのサービスのいずれかがエラーをスローし、まだ .catch 関数がアタッチされていない場合、後で指定された .catch() 関数に送信するためにエラーを保持しますが、コンソール エラーもスローします。彼らはcatch関数が添付されるかどうかを知りません.promiseが黙って失敗し、エラーが消えたらイライラするでしょう.

本当に promisesArray を baseService() の後に実行したい場合は、promisesArray を非同期タスクを開始して promise を返す関数の配列にするというアイデアは良いものです。ただし、(前述のように) promise を返す関数の配列を渡すよりも、promise の配列を返す関数を渡す方が適切な場合があります。

const getPromises = () => [
    service1.load('blabla'),
    service2.load(), // throws an errors
]

次に、を使用して実行します

baseService()
    .then(() => Promise.all(getPromises()))
    .catch((err) => handleError(err));

これは、baseServce() が完了した後にのみ service1.load を開始し、すべてのエラーは発生するとすぐにキャッチされます

于 2017-06-13T01:38:00.140 に答える
0

私はそれを機能させる方法を考え出しました。

promise の配列の代わりに、Promise を返す関数の配列を作成します。

let promisesArray = [
    () => service1.load('blabla'),
    () => service2.load(), // throws an errors
];
promisesArray.push(() => service2.load())

それから私Array.prototype.map()は約束を実行するために使用しますPromise.all():

baseService()
    .then(() => Promise.all(promisesArray.map(promise => promise())))
    .catch((err) => handleError(err));

それが私の問題を解決していますが、それが最善の方法であるかどうかはわかりません。誰かがより良いアイデアを持っているなら、私はそれを取ります。

于 2016-07-22T12:25:09.097 に答える