2017-05-01 2 views
1

私は、約束が遂行されたり拒否されたりすることはないので、JavaScriptランタイムは単に終了し、awaitのコードは決して実行されないため、次のスニペットが永遠にハングすることを期待していました。上記にも動的起こることより悪い何空のJavaScript Promiseを待っていると、ランタイムが有効に保たれません。

(async function() { 
 
    console.log('so far so good'); 
 
    await new Promise(() => {}); 
 
    console.log('never printed'); 
 
})();

プロミスが生きランタイムを保つ/満たすだけで、次の例のために、特定のイベントの後に拒否することが不可能になった場合つまり、あります

(async function() { 
 
    console.log('so far so good'); 
 
    await new Promise((fulfill, reject) => { 
 
     const timeout = setTimeout(fulfill, 2000); 
 
     setTimeout(() => { 
 
      clearTimeout(timeout); 
 
     }, 1000); 
 
    }); 
 
    console.log('never printed'); 
 
})();

:1秒間

これは背後にある理由は何ですか?もっと重要なのは、この振る舞いを扱うドキュメント/スペックにリンクすることができますか?

+1

申し訳ありませんが、私は本当にそれを取得しません。 *ブロッキング*とはどういう意味ですか? – Vinz243

+0

もっと重要なのは、1秒間しかブロックされていないことが示され、残りは実行されません。 – Vinz243

+1

"ブロックする"と "ランタイムが生きている"と混同していると思います。 – Bergi

答えて

3

満たされていない約束は、それ自体で生きているのNode.jsを保持しません。 node.jsが自動的に生き続けるためには、まだ生きていない基本的な未完成の非同期操作(通常は背後にいくつかのネイティブコードがある)が必要です。自動的にNode.jsのキープアライブ物事の

例としては

満たされていない約束はちょうどメモリに座っJavaScriptオブジェクトです...など解雇されていないオープンソケット、タイマ、です。それはnode.jsの他のオブジェクトよりもnode.jsプロセスの存続期間に影響を与えません。約束は、特定の操作(特別な機能を備えたイベントエミッターのようなもの)の解決または拒否イベントに関心を登録できる通知スキームです。基本的な非同期操作(通常、非同期操作を実行するネイティブコードによってサポートされています)が、実際にプロセスを開いたままにします。約束自体は、プロセス自体にまったく影響を与えません。

+0

まだまだ私は得られないことがあります...完成していないPromiseがNode.jsの実行を維持するのに十分ではないが、残りの非同期関数については何もしていないことは間違いありませんか?それはまだ生きていない未完成の非同期操作ですか? – cYrus

+0

@cyrus - 特定の非同期操作について質問できますか? – jfriend00

+0

上記の2つの例のそれぞれでは、 'async'関数が開始され、決して完了しません。つまり、' await'の後のコードは実行時が終了するため決して実行されません。そのようなコードは最終的に実行されるはずですか? – cYrus

1

限り、私はここにあなたの混乱を理解できるよう、説明がある:あなたが非同期関数を記述すると、それはのawaitの発現が解決されることはありませんし、その約束が保留されているように解決されていない約束を

返します。 価値ありreadh:mdn doc for async

これでメインスレッドの実行はブロックされません。どのような未解決の約束に起こることはSOの答えの一つにここで読むことができます:unresolved promises

0

あなたの非同期機能だけですぐに終了しているとはあなたに約束を返します。次のことを試してみてください。

var myAsync = async function() { 
 
    console.log("inside myAsync - before resolving"); 
 
    await new Promise(resolve => { 
 
     setTimeout(() => { 
 
     resolve(); 
 
     }, 1000);}); 
 
    console.log("inside myAsync - after resolving"); 
 
}; 
 

 
console.log("after declaring myAsync"); 
 
myAsync().then(() => {console.log("myAsync has resolved")});

setTimeoutは無限(またはあなたはそれを完全に削除した場合)に設定されていた場合、あなただけ「myAsync内部は」が続くになるだろう「myAsyncを宣言した後"。結局のところ、この仕組みの全体的なポイントはデッドロックを防ぐことです。

出典:async function in MDN

関連する問題