地獄の解決方法のまとめ

6001 ワード

非同期プログラミングはJavaScriptにおいて非常に重要であり、多すぎる非同期プログラミングもエコーネストの問題を持っている.【逆転地獄】
1、分解function:各ステップを単一のfunctionに分解する
2、イベントのリリース/モニターモード:
一方、ある事件を傍受し、事件が発生した時に、相応の調整操作を行う.一方、いくつかの動作が完了すると、イベントトリガー・リプライを発行することにより、元々一緒に縛られていたコードを結合することができる.
3、Promise
readFile('./sample.txt').then(content => {
    let keyword = content.substring(0, 5);
    return queryDB(keyword);
}).then(res => {
    return getData(res.length);
}).then(data => {
    console.log(data);
}).catch(err => {
    console.warn(err);
});
4、ゲナート
generatorはes 6の中の新しい文法です.functionキーの後に*を追加すると、関数をgeneratorに変更できます.
const gen = function* () {
    yield 1;
    yield 2;
    return 3;
}
generatorを実行すると、generatorの内部を巡回するためのエルゴードオブジェクトが返されます.
let g = gen();
g.next(); // { value: 1, done: false }
g.next(); // { value: 2, done: false }
g.next(); // { value: 3, done: true }
g.next(); // { value: undefined, done: true }
generator関数には最大の特徴があり、内部で実行する過程でプログラムの制御権を引き出すことができ、yieldは一時停止の役割を果たしたに相当する.一定の場合は、外部から制御権を引き継ぎます.想像してみてください.私たちはgeneratorでコードをカプセル化して、非同期のタスクでyieldのキーワードを使って、この時generatorはプログラム実行権を他のコードに渡します.非同期のタスクが完了したら、nextメソッドを呼び出して、yieldの下のコードの実行を回復します.readFileを例にとって、大まかな流れは以下の通りである.
//       ——     //   yield          // yield   promise  
const showKeyword = function* (filepath) {
    console.log('    ');
    let keyword = yield readFile(filepath);
    console.log(`    ${filepath}`);
}
// generator     
let gen = showKeyword();
let res = gen.next();
res.value.then(res => gen.next(res));
5、async/await
上記の方法は、非同期プログラムにおけるコールバックによる問題をある程度解決しているが、これは明らかである.しかしながら、
  • function分割の方法は、実際には単にコードブロックを分割するだけで、しばしば後続の維持に不利である.
  • イベントの発表/傍受方式は非同期方法間の流れ関係をぼかしている.
  • Promiseは、複数の入れ子の非同期呼び出しをチェーン式APIによって操作できるようにしたが、多すぎるthenもコードの冗長性を増加させ、コードを読む各段階の非同期タスクに一定の干渉を与えた.
  • ゲナートを通じて、より良い文法構造を提供することができますが、ゲナートとエディドの文脈はここでは多少適切ではありません.そこで、ここでもう一つの方法を紹介します.これはes 7のasync/awaitです.簡単にasync/awaitを紹介します.基本的に、どの関数もasync関数になります.以下は合法的な書き方です.
    async function foo () {};
    const foo = async function () {};
    const foo = async () => {};
     async       awaitawait      Promise  。
    async function foo () {
        console.log('  ');
        let res = await post(data);
        console.log(`post   ,   :${res}`);
    };
    上の関数がawaitに実行されると、関数が保留され、await後のPromiseが戻ってくるのを待って、次のような文が実行されると簡単に理解できます.なお、この非同期動作のコードは、「同期動作」のように見える.これは大幅に非同期コードの作成と読みに便利です.私たちの例を書き直します.
    const printData = async function (filepath) {
       let keyword = await readFile(filepath);
       let count = await queryDB(keyword);
       let data = await getData(res.length);
       console.log(data);
    });
    printData('./sample.txt');
    コードが簡潔で明瞭で、非同期コードも「同期」コードの構造を持っていることが分かる.なお、readFile、queryDB、getData方法は、Promiseオブジェクトに戻る必要があります.これは第三部分Promiseで提供された方式で書き換えることができます.