ES 6のGenerator
18020 ワード
ES 6中Generator
GeneratorはES 6の興味深い特性であり、理解しにくい特性でもあります.
まず、JavaScriptにおいて、どの関数も実行を開始すると、実行が完了するまで停止できなくなります.
but,Generatorはこの能力を提供します.次のコードを見てください
ここに来て、私達は知る必要があります. Generatorは関数ではなく、関数ではない. g()はすぐに実行に出発しないで、上がってきたら一時停止して、Iteratorオブジェクトに戻ります. 毎回g 1.next()は一時停止状態を破って実行します.次のyieldまたはreturn に出会うまで.がyieldに会った時、yeildの後の表現を実行して、実行後の値を返して、再度一時停止状態に入ります.この時done:false. がreturnに会ったら、値を返します.実行が終了します.すなわちdone:true 毎回g.next()の戻り値は永遠にすべてvalue:…,done:…)の形です.
Generatorと非同期
Generatorが関数を止められるなら、一部の脳洞清奇な人はGeneratorで非同期プログラムを処理してもいいかと思いました.
まず伝統的な例を見ます.
上記の手順では、
GeneratorとKooa
KooaはNode.jsに基づくWebアプリケーションのフレームワークである.Kooでは、処理の非同期プログラムは、主にネットワーク要求(HTTP)、ファイル読み込み、およびデータクエリである.この中の非同期シーンが多いです.プログラムの階層を加えて、伝統的なcalback方式を採用すると、その回数が多くなります.
最新のKoo 2ではGenetatorを捨てて
しかし、どのような方式を採用しても、その本質はPromiseを利用したのです.
GeneratorはES 6の興味深い特性であり、理解しにくい特性でもあります.
let/const
がブロックレベルのスコープを提供したという明白な目的とは違って、このようなものが作られたのは一体何ですか?まず、JavaScriptにおいて、どの関数も実行を開始すると、実行が完了するまで停止できなくなります.
but,Generatorはこの能力を提供します.次のコードを見てください
function *g(){
console.log('start');
yield 1;
console.log('middle');
yield 2;
console.log('end');
}
var g1 = g();
console.log(g1.next());
// start
// {value: 1, done: false}
console.log(g1.next());
// middle
// {value: 2, done: false}
console.log(g1.next());
// end
// {value: undefined, done: true}
出力結果によると、関数g
にyield
のキーワードがあり、実行中のプログラムが停止することを確認しました.関数next()
のコードは、g
の方法を呼び出してのみ実行される.したがって、関数g
自体に一時停止状態がある.ここに来て、私達は知る必要があります.
Generatorと非同期
Generatorが関数を止められるなら、一部の脳洞清奇な人はGeneratorで非同期プログラムを処理してもいいかと思いました.
まず伝統的な例を見ます.
function asyn(fn) {
return new Promise((resolve,reject)=>{
setTimeout(()=>{
fn();
resolve(true);
}, 1000);
});
}
function main() {
console.log('start');
asyn(function(d) {
console.log('async one');
asyn(function(d) {
console.log('async two');
console.log('end');
});
});
}
main();
また、Generatorを使った非同期プログラムを見てください. function asyn(fn) {
return new Promise((resolve,reject)=>{
setTimeout(()=>{
fn();
resolve(true);
}, 1000);
});
}
co(function*() {
console.log('start');
yield asyn(function(d) {
console.log('async one');
});
yield asyn(function(d) {
console.log('async two');
});
console.log('end');
});
function co(fn) {
return new Promise((resolve,reject)=>{
let g = fn();
onFullfilled();
function onFullfilled() {
let ret = null;
ret = g.next();
next(ret);
}
function next(ret) {
if(ret.done) return resolve(ret.value);
ret.value.then(onFullfilled);
}
} );
}
関数は非同期プログラムに入れ子のコールバックを使用していません.直接同期方式で書きました.道理は大体、二つの非同期プログラムがあります.明と紅を使ってそれらを指します.紅ちゃんは明さんの実行が終わったら実行できます.そうすると、私達は明さんに実行する時、プログラムの実行を一時停止します.(yield
を通じて)明さんが帰ってきた時、後に付いてくる紅ちゃんを実行します.上記の手順では、
next()
関数を追加しました.この関数の役割はGeneratorに自動的に実行させます.直接的には、第1の非同期関数が戻った後に、自動的にco
メソッドを呼び出して、後のコードを実行します.GeneratorとKooa
KooaはNode.jsに基づくWebアプリケーションのフレームワークである.Kooでは、処理の非同期プログラムは、主にネットワーク要求(HTTP)、ファイル読み込み、およびデータクエリである.この中の非同期シーンが多いです.プログラムの階層を加えて、伝統的なcalback方式を採用すると、その回数が多くなります.
app.on('get', function(){
auth(function(){
router(function(){
find(function(){
save(function(){
render(function(){
//......
})
})
})
})
})
})
このような書き方はプログラムの維持と不利で、便利さがまったくないです.generatorができたら、上のようにプログラムを書くことができます.Koraの最初のバージョンはこのようにして中間処理プログラムを一つずつ「yield」(中間部品)にします.中間部品の形式でクライアント要求を処理することにより、開発Appアプリケーションをより柔軟にし、フレーム自体に制限されない.最新のKoo 2ではGenetatorを捨てて
next()
を使用します.しかし、どのような方式を採用しても、その本質はPromiseを利用したのです.