web-dev-qa-db-ja.com

「Promise.resolve()。then()」に相当するものを待ちますか?

私はPromiseに精通していますが、new Promise()がコンストラクターのメソッドを使用するのではなく、かなり変わったコードを継承しています。

Promise.resolve().then(
  function() {
    // Do useful things
  }
)

私の研究によると、これは 奇妙なバージョンのsetImmediate です。つまり、次のティックで次の関数を実行します。

これのawaitバージョンはどうなりますか?

15
mikemaccana

Promise.resolve()には2つの理由があります。あなたはそれらの1つに触れました:

JSイベントループの現在の実行が終了するまで延期する

ここでの明白な答えはawait Promise.resolve();です。

_await undefined_は暗黙的に同じことを行いますが、なぜ明示的にしないのですか?

特異なエラー処理

Promise.resolve()は、単一のエラー処理のpromiseチェーンの先頭にもよく見られます。

_const doSomething = x => new Promise(r => setTimeout(() => r(x), 1000));

Promise.resolve()
.then(() => doSomething(""())) // bug!
.then(() => doSomething("else"))
.catch(e => console.log("Got " + e)); // Got TypeError: "" is not a function_

これがないと、最初のステップが代わりに例外をスローする可能性があり、これは予期しない可能性があります。

_const doSomething = x => new Promise(r => setTimeout(() => r(x), 1000));

doSomething(""()) // bug!
.then(() => doSomething("else"))
.catch(e => console.log("Got " + e)); // uncaught!_

ここでの答えは、async/awaitを使用したPromise.resolve()プロローグが不要になったことです。

async関数は暗黙的に同期例外をキャッチし、代わりに拒否されたpromiseを返します。これにより、単一のエラー処理とpromiseの戻り値が保証されます。

_const doSomething = x => new Promise(r => setTimeout(() => r(x), 1000));

(async () => {
  await doSomething(""()); // bug!
  await doSomething("else");
})().catch(e => console.log("Got " + e)); // Got TypeError: "" is not a function_

Promise.resolve() kludgeとは異なり、これはナイスインバリアントであり、入力が少ないだけでなく、実際にはdoSomethingを同期的に呼び出します。

_function doSomething() {
  console.log("doSomething() called");
  ""() // bug!
  return new Promise(r => setTimeout(() => r(x), 1000));
}

(async () => {
  await doSomething();
  await doSomething("else");
})().catch(e => console.log("Got " + e)); // Got TypeError: "" is not a function

console.log("here");_

これは、他の方法ではうまくいきません。 async/awaitが優れているもう1つの理由!

10
jib

ただawait何か。

awaitにプロミスではない式を与えると、次のように動作します

await Promise.resolve(<nonPromiseExpression>)

そう await undefinedを指定すると、残りの非同期関数が非同期で実行されます。例として、これら2つのsetImmediateの実装を取り上げます。

var setImmediate = function (fn) {
  Promise.resolve().then(fn);
};

console.log('A');
setImmediate(function () {
  console.log('E');
});
console.log('B');

setImmediate = async function (fn) {
  await undefined;
  fn();
};

console.log('C');
setImmediate(function () {
  console.log('F');
});
console.log('D');
4
PeterMader

私はnew Promise()を使用するのではなく、Promise.resolve().then(…)を使用するというかなり珍しいコードを継承しています。私の調査によると、これはsetImmediateの奇妙なバージョンです。つまり、次のティックで次の関数を実行します。

これは副作用ですが、おそらくこの構造の意図した目的ではありません。重要な点は、thenコールバックの「有用なコード」がthrow- safeであり、単純なreturn単純な値とプロミスを簡単に行うことができ、通常のプロミスチェーンを開始することです。 couldも_new Promise_で記述されていますが、通常のresolveの代わりにreturn呼び出しを使用する必要がありました。

これのawaitバージョンは何でしょうか?

文字通り、await Promise.resolve();(これは、同等の_await;_ステートメントに短縮できます)。ただし、エラー処理のみの目的で行われた場合は(おそらく)、省略します。 _async function_ sは、デフォルトで例外を拒否に変換します。

4
Bergi