私はしばらくBabelを使用していますが、とても気に入っています。ただし、サポートされている機能を一覧表示しているホームページには、Async functions
.
私は多くのグーグルを行ってきましたが、理解できるように見えるのは、それがES7の機能であることだけです。
ES7非同期関数とは何ですか?
私はしばらくBabelを使用していますが、とても気に入っています。ただし、サポートされている機能を一覧表示しているホームページには、Async functions
.
私は多くのグーグルを行ってきましたが、理解できるように見えるのは、それがES7の機能であることだけです。
ES7非同期関数とは何ですか?
ES2016 (一般に ES7 または ECMAScript 7 と呼ばれる) は、ECMA-262 標準 (一般に JavaScript と呼ばれる) の次の進化であり、まだ初期段階にあります。
非同期関数は、ES2016 標準の一部として提案された新しい JavaScript 機能であり、まだどのブラウザーでもサポートされていません。それらはpromiseの上に構築されています。
さまざまな信頼できる情報源からのこの新機能の紹介については、以下を参照してください。
非同期関数は一般的にES7 asynch functions
(たとえば、async.jsまたは一般的な非同期 JavaScriptとのあいまいさをなくすために) と呼ばれますが、 Axel Rauschmayerはそれらを と呼ばないことを推奨しています。ステージ4になりました。
非同期関数は現在、ステージ 3 のみです。実際、ES2016 には非同期関数が含まれていない可能性があります(以下のコメントでFelix Klingが指摘したように)。
ステージ 3 の提案から:
序章
ECMAScript でのプロミスとジェネレーターの導入は、ECMAScript で非同期コードを記述するための言語レベルのモデルを劇的に改善する機会を提供します。
同様の提案が、ES6 の議論中にDeferred Functionsで行われました。ここでの提案は、同様または同じ構文を使用して同じユース ケースをサポートしますが、ジェネレーターの構造と同様の制御フロー構造に直接構築し、カスタム メカニズムを定義する代わりに戻り値の型に promise を使用します。
この提案の開発は https://github.com/tc39/ecmascript-asyncawaitで行われています。そこに問題を提出してください。重要な貢献は TC39 メンバーに限定されますが、マイナーな問題のプル リクエストは歓迎され、奨励されます。
この提案のステータス
この提案は、2015 年 9 月に ECMAScript仕様プロセスのステージ 3 (「候補」) に受け入れられました。チャンピオンは、この提案が 11 月末までにステージ 4 (「完了」) に受け入れられることを意図しています。
例
Promises を使用して最初に記述された次の例を見てみましょう。このコードは要素の一連のアニメーションをチェーンし、アニメーションに例外があると停止し、正常に実行された最終的なアニメーションによって生成された値を返します。
function chainAnimationsPromise(elem, animations) { let ret = null; let p = currentPromise; for(const anim of animations) { p = p.then(function(val) { ret = val; return anim(elem); }) } return p.catch(function(e) { /* ignore and keep going */ }).then(function() { return ret; }); }
すでに promise があるため、コードは、この種のループと例外処理が困難な単純なコールバック スタイルから大幅に改善されています。
Task.jsおよび同様のライブラリは、ジェネレーターを使用してコードをさらに簡素化し、同じ意味を維持する方法を提供します。
function chainAnimationsGenerator(elem, animations) { return spawn(function*() { let ret = null; try { for(const anim of animations) { ret = yield anim(elem); } } catch(e) { /* ignore and keep going */ } return ret; }); }
これは顕著な改善です。コードのセマンティック コンテンツを超えるプロミスのボイラープレートはすべて削除され、内部関数の本体がユーザーの意図を表します。ただし、追加のジェネレーター関数でコードをラップし、それをライブラリーに渡して promise に変換するボイラープレートの外側の層があります。このレイヤーは、このメカニズムを使用して promise を生成するすべての関数で繰り返す必要があります。これは典型的な非同期 Javascript コードでは非常に一般的であるため、残りのボイラープレートの必要性を取り除くことに価値があります。
非同期関数を使用すると、残りのボイラープレートがすべて削除され、意味的に意味のあるコードのみがプログラム テキストに残ります。
async function chainAnimationsAsync(elem, animations) { let ret = null; try { for(const anim of animations) { ret = await anim(elem); } } catch(e) { /* ignore and keep going */ } return ret; }
Jake Archibaldの記事ES7 async functionsから:
promise との非同期
promises に関する HTML5Rocks の記事の最後の例では、ストーリーの JSON データをロードし、それを使用してチャプターの JSON データをさらにフェッチし、チャプターが到着したらすぐに順番にレンダリングする方法を示しています。
コードは次のようになります。
function loadStory() { return getJSON('story.json').then(function(story) { addHtmlToPage(story.heading); return story.chapterURLs.map(getJSON) .reduce(function(chain, chapterPromise) { return chain.then(function() { return chapterPromise; }).then(function(chapter) { addHtmlToPage(chapter.html); }); }, Promise.resolve()); }).then(function() { addTextToPage("All done"); }).catch(function(err) { addTextToPage("Argh, broken: " + err.message); }).then(function() { document.querySelector('.spinner').style.display = 'none'; }); }
悪くはありませんが…</p>
今回は ES7 の非同期関数で…</h3>
async function loadStory() { try { let story = await getJSON('story.json'); addHtmlToPage(story.heading); for (let chapter of story.chapterURLs.map(getJSON)) { addHtmlToPage((await chapter).html); } addTextToPage("All done"); } catch (err) { addTextToPage("Argh, broken: " + err.message); } document.querySelector('.spinner').style.display = 'none'; }
非同期関数 (完全な提案) を使用する
await
と、約束を果たすことができます。これにより、ブロックされない方法で関数が停止し、promise が解決されるのを待ち、値が返されます。promise が拒否された場合、拒否値でスローされるため、 を使用して処理できますcatch
。編集:私はもともと
await
アロー関数内で使用していましたが、明らかに許可されていないfor
ため、 ループに置き換えました。Domenic は、なぜawait
をアロー関数で使用できないのかについて、私に知識を教えてくれました。
loadStory
promise を返すので、他の非同期関数で使用できます。(async function() { await loadStory(); console.log("Yey, story successfully loaded!"); }());
KoaJSの記事The Evolution of Asynchronous JavaScriptから:
ジェネレーター/収量
JavaScript ジェネレーターは比較的新しい概念で、ES6 (ES2015 とも呼ばれます) で導入されました。
関数を実行するときに、任意の時点で関数を一時停止し、別の計算を行い、別のことを行ってから、何らかの値があっても関数に戻って続行できると便利だと思いませんか?
これはまさにジェネレーター関数が行うことです。ジェネレーター関数を呼び出しても実行が開始されないため、手動で反復処理する必要があります。
function* foo () { var index = 0; while (index < 2) { yield index++; } } var bar = foo(); console.log(bar.next()); // { value: 0, done: false } console.log(bar.next()); // { value: 1, done: false } console.log(bar.next()); // { value: undefined, done: true }
ジェネレーターを使用して非同期 JavaScript を簡単に記述したい場合は、coも必要になります。
Co は Node.js とブラウザーの優れた制御フローを生成するジェネレーターであり、Promise を使用して、ノンブロッキング コードを適切な方法で記述できます。
では
co
、前の例は次のようになります。co(function* (){ yield Something.save(); }).then(function() { // success }) .catch(function(err) { //error handling });
並行して実行されている操作についてはどうですか? 答えはあなたが思っているよりも簡単です (ボンネットの下ではただの
Promise.all
):yield [Something.save(), Otherthing.save()];
非同期/待機
非同期関数は ES7 で導入されました。現在、babel のようなトランスパイラーを使用してのみ使用できます。(免責事項: ここでは、async パッケージではなく、async キーワードについて話しています)
要するに、キーワードを使用すると、と ジェネレーター
async
の組み合わせで行っていることを行うことができます- ハッキングは除きます。co
Promises
async
を使用した内部関数 - これが、非同期関数がPromise
.