web-dev-qa-db-ja.com

ES6 Promises-promiseチェーン内の同期関数の呼び出し

私は現在、約束を試していますが、本当に基本的な質問があります!

Promiseチェーン内で、同期関数を呼び出すのは悪い習慣でしょうか?例えば:

.then(function(results) {

    if(checkIfResultInMemory(results) === true){
       return getTotalFromMemory()
    }

   return results;

  })

または、約束を返すように同期関数をリファクタリングする必要がありますか?

15
Ben

Promiseチェーン内で、同期関数を呼び出すのは悪い習慣でしょうか?

いいえ、それは悪い習慣ではありません。これは、多くの期待される有用なプラクティスの1つです。

Promiseチェーン内の同期関数(.then()ハンドラー内から)、または新しいpromiseを返す非同期関数を完全に自由に呼び出すことができます。

.then()ハンドラーから何かを返すときは、値(親プロミスの解決された値になります)または別のプロミス(前のプロミスにチェーン)を返すか、スローすることができますこれは、拒否された約束を返すように機能します(約束の連鎖は拒否されます)。

つまり、同期関数を呼び出してその関数から値を取得するか、非同期関数を呼び出して別のプロミスを取得してから.then()ハンドラーから返すことができるということです。

これらの同期的なものはすべて完全に合法であり、それぞれに独自の目的があります。 .then()ハンドラーでの同期的な出来事を次に示します。

_// modify resolved value
someAsync().then(function(val) {
    return val + 12;
});

// modify resolved value by calling some synchronous function to process it
someAsync().then(function(val) {
    return someSynchronousFunction(val);
});

// synchronously check the value and throw to change the promise chain
// to rejected
someAsync().then(function(val) {
    if (val < 0) {
        throw new Error("value can't be less than zero");
    }
    return val;
});

// synchronously check the value and return a rejected promise 
// to change the promise chain to rejected
someAsync().then(function(val) {
    if (val < 0) {
        return Promise.reject("value can't be less than zero");
    }
    return val;
});
_

次に、3つの同期.then()ハンドラーが続くプロミスを返し、最終値を出力する非同期操作の小さな例を示します。

_function delay(t, val) {
    return new Promise(function(resolve) {
        setTimeout(function() {
            resolve(val);
        }, t);
    });
}

function increment5(val) {
    return val + 5;
}

delay(500, 10).then(increment5).then(function(val) {
    return val - 3;
}).then(function(final) {
    document.write(final);
});_

注:通常、すべてが同期である場合、純粋な同期コードは実行が速く、記述しやすいため、非同期操作がある場合、または非同期操作がある場合にのみプロミスを使用します。ただし、少なくとも1つの非同期操作が既にある場合は、同期操作とその非同期操作を混在させて、Promiseを使用してコードを構造化することができます。

27
jfriend00

thenコールバック関数は:

  • 別の約束を返す
  • 同期値を返します(または未定義)
  • 同期エラーをスローします
2
trquoccuong