web-dev-qa-db-ja.com

依存するPromiseをフラット化する利点は何ですか

Promiseの継続を​​ネストすることは悪い習慣であることを読みました。たとえば、 ここ

GetCustomer().then(customer => {
    ProcessCustomer(customer).then(processingResult =>
    {
        console.log(customer);
        console.log(processingResult);
    });
});

2番目の関数呼び出しは最初の関数呼び出しに依存しているため、ネストを解除すると次のようになります...

GetCustomer().then(customer => {
        return Promise.all([customer, ProcessCustomer(customer)]);
    }).then(results => {
        console.log(results[0]);
        console.log(results[1]);
    });

私は個人的に、ネストされたスタイルが読みやすく、推論しやすいと感じています。また、エラーが発生しやすいresults[i]にアクセスするのとは対照的に、厳密に名前が付けられた変数も気に入っています。

最初のアプローチの欠点、および/または2番目のアプローチの利点は何ですか?

2
Tom Bowers

ネストせずにcustomerprocessingResultの両方にアクセスする最も簡単なオプションは、おそらくこのように_async/await_(ES7機能)を使用することです(これはasync関数宣言):

_async function someFunction() {
    const customer = await GetCustomer();
    const processingResult = await ProcessCustomer(customer);
    console.log(customer);
    console.log(processingResult);
    return someValue;
}

// usage
someFunction().then(result => {
    // done here
}).catch(err => {
    console.log(err);
});
_

最初のアプローチの欠点は何ですか、

このような2つのレベルでは、ネストに特に不利な点はありません。最終結果と完全なエラー処理を取得できるようにするには、内部のpromiseを返す必要があります。したがって、ネストで最初のオプションを適切に使用するには、少なくとも内部のpromiseを返して、トップレベルですべてのエラーをキャッチできるようにする必要があります。

_GetCustomer().then(customer => {
    return ProcessCustomer(customer).then(processingResult => {
        console.log(customer);
        console.log(processingResult);
        return someValue;
    });
}).catch(err => {
    // catch all errors here
    console.log(err);
});
_

より多くのレベルを取得すると、ネストはますます読みにくくなります。

および/または2番目の利点?

現時点では、これは本当に個人的な意見です。私は個人的には、生の値をPromise.all()に渡すのが好きではないので、一般的な.then()ハンドラーに渡します。コードが実際よりも複雑に見えるように見えます(しかし、それは私の意見です)。それはうまくいくでしょう。

これは、オブジェクトを破壊すると物事が少し読みやすくなり、.catch()ハンドラーが必要になる場所です。

_GetCustomer().then(customer => {
    return Promise.all([customer, ProcessCustomer(customer)]);
}).then(([customer, processedCustomer]) => {
    console.log(customer);
    console.log(processedCustomer);
}).catch(err => {
    console.log(err);
});
_

その他のオプションについては、こちらをご覧ください。

以前の結果を約束と連鎖させて共有する方法

2
jfriend00