blog

ジェネレータと Promise非同期awaitの関係を理解する

ジェネレーターとは? 従来の関数: function a {\n return 'hellox20' + obj;\n}\n(a...

Jan 16, 2021 · 3 min. read
シェア

発電機とは何ですか?

発電機の形態

伝統的な機能:

function hello(name){
 
 return "hello " + name;
}
console.log(hello('james')); // hello james

generator 関数を定義します:

function* hello(name){
 return "hello " + name;
} 
consolo.log(hello('james)); // Object [Generator] {}
console.log(hello('james').next()); //{ value: 'hello james', done: true }

上記のジェネレータ定義関数は、通常の関数と比較して、*記号以上に見ることができます。generator.next()シングルステップの実行を介して、nextは、値とdoneを含むオブジェクトを返し、計算の結果は、現在のプロシージャの値、およびdoneは、実装が完了したかどうかをプログラムで表現されています。

上記のフィールド式の実行に一時停止があるとマークの実行を一時停止することです、次の実行を再開することです。

const hello = function* (data){ 
 const {name1, name2} = {...data}; 
 yield "hello "+name1; 
 yield "hello "+name2; 
 return 'success';
}
const obj = hello({'name1':'aaa','name2':'bbb'});
console.log(obj.next()); //{ value: 'hello aaa', done: false }
console.log(obj.next()); //{ value: 'hello bbb', done: false }
console.log(obj.next()); //{ value: 'success', done: true }



Promiseとは
Promiseはes6の非同期プログラミングのソリューションで、Promise自体はコンストラクタで、all、reject、resolveなどのメソッド、prototype then、catchなどのメソッドを持っています。以下はPromiseの使い方を理解するためのコラムです:

new Promise((reject, resolve) => {
 setTimeout(function(){
 resolve('seccess');
 }, 2000);
}).then((data) => {
 console.log(data); //seccess
});

resolveはPromiseの状態をfullfiledに設定し、rejectはPromiseの状態をrejectに設定します。rejectまたはresolveの後に、最後のステートの値を削除する関数を実行します。こうすることで、コールバック関数の実行後に、コールバックメソッドと非同期処理を連鎖呼び出しの形で分離することができます。

チェーン・コールの代わりにジェネレータ・ジェネレータ

let asyncfunc = (a, b)=>{ 
 return new Promise((resolve, reject) => { 
 setTimeout(()=>{ 
 resolve(a+b); 
 }, 1000); 
 });} 
let g = function* (){ 
 let res = yield asyncfunc(2,2); 
 return res;
}
let item = g();
let p = item.next().value;
p.then((sum)=>{ 
 console.log(item.next(sum));
});

以下は、nextの繰り返し呼び出しを排除するために再帰を使用して、ジェネレーターの自動反復を実装するためにデリゲートパターンを使用しています。

let asyncfunc = (a, b)=>{ 
 return new Promise((resolve, reject) => { 
 setTimeout(()=>{ 
 resolve(a+b); 
 }, 1000); 
 });
} 
let g = function* (){ 
 let res = yield asyncfunc(2,2); 
 return res;
}
function Co(item){ 
 return new Promise((res, rej) =>{ 
 let next = (data) => { 
 let {value, done } = item.next(data); 
 if(done){ 
 res(value); 
 }else{ 
 value.then((value) =>{ 
 next(value); 
 }, rej); 
 } 
 }; 
 next(); 
 });
}
Co(g()).then((val)=>{ 
 console.log(val);
});

非同期+await

let asyncfunc = (a, b)=>{ 
 return new Promise((resolve, reject) => { 
 setTimeout(()=>{ 
 resolve(a+b); 
 }, 1000); 
 });
} 
let g = async function(){ 
 let res = await asyncfunc(2,2); 
 return res;
}
g().then((data)=>{ 
 console.log(data);
});
asyncは完全に書かれたコードの順序に従ってタスクの同期実行に変換された非同期連鎖ネストタスクになり、ここで同期タスクは、async +内部非同期タスクのawait制御による同期タスクを指し、async関数自体が非同期タスクであり、それはリターンの実行は、最終的なコールバック処理の非同期連鎖タスクを処理するために使用されるPromiseオブジェクトです。



Read next

Netty学習シリーズ(VII) - まとめ

今回はNettyに関する最後の投稿で、Nettyについて学んだことや私自身の洞察をまとめます。さらに、Nettyで使われているいくつかのデザインパターンを分析し、最後にこのシリーズで学んだことをまとめます。 このセクションでは、Nettyとは何か、なぜこのライブラリが作られたのか、そしてNettyが何を提供するのかについて説明します。

Jan 16, 2021 · 26 min read