[英]Javascript ES6 generator async
我需要運行生成器異步(我需要在控制台1,2,3,4,5中導致結果現在我有4,1,2,3,5)任何人都可以幫助我嗎? 我需要運行任務並等待上一個任務完成后再運行下一個任務。 我需要使用(如果可能的話)發電機(或發電機+承諾?)
在這里我的代碼
/*jshint esnext: true */
function show(msg) {
var _msg = msg;
setTimeout(function() { console.log(_msg);}, 2000);
}
function show2(msg) {
console.log(msg);
}
var stack = [];
// add some function to stack
stack.push(function() { show(1); });
stack.push(function() { show(2); });
stack.push(function() { show(3); });
stack.push(function() { show2(4); });
stack.push(function() { show(5); });
function* generator1() {
for(var key of stack) {
yield key();
}
}
var gen = generator1();
gen.next();
gen.next();
gen.next();
gen.next();
gen.next();
這可以完全用發電機完成。 下面是一種方法的示例,其中我們將.next()
移動到超時本身,以確保它不會提前發生。 此外,生成器現在將函數從堆棧中返回而不是執行它,因為您無法在生成器本身的執行中調用生成器上的.next()
。
值得注意的是,這可能不是我在野外做到這一點的方式; 我會包括承諾。 但是你問過它是否只能用一台發電機來完成 - 答案是'是'。
function show(msg) {
var _msg = msg;
setTimeout(function() {
console.log(_msg);
execute();
}, 2000);
}
function show2(msg) {
console.log(msg);
execute();
}
var stack = [];
function execute() {
var fn = gen.next().value;
if (fn) fn();
}
// add some function to stack
stack.push(function() { show(1); });
stack.push(function() { show(2); });
stack.push(function() { show(3); });
stack.push(function() { show2(4); });
stack.push(function() { show(5); });
function* generator1() {
for(var key of stack) {
yield key;
}
}
var gen = generator1();
execute();
這有很多“任務運行”功能,你甚至可以編寫自己的功能。 但是你必須為此使用Promises,而不是setTimeout
。 這是一個簡單的例子:
function delay (ms, val) { return new Promise(function (res) { setTimeout(res, ms || 1000, val || Math.random()); }); } function* run () { yield delay(); console.log(yield delay()); yield delay(); console.log('foo'); // sync calls anywhere in between console.log(yield delay()); } function async(gen){ "use strict"; gen = gen(); return Promise.resolve().then(function cont(a){ var n = gen.next(a), v = Promise.resolve(n.value); if(n.done) return v; // a `return` return n.value.catch(gen.throw.bind(gen)).then(cont); }); }; async(run);
基本上,我們調用生成器的next
方法,等待它完成,然后再次觸發next
方法,然后遞歸直到生成器停止。
Bluebird有一個名為Promise.coroutine
的更多故障保護功能。
Task.js: http ://taskjs.org/專門為此提供了一個功能。
希望有所幫助!
您需要一種方法讓您的功能告訴它們何時完成。 承諾是解決這個問題的好方法。
我會盡可能地堅持原始代碼:
function show(msg) {
return new Promise(function(resolve){
var _msg = msg;
setTimeout(function() { console.log(_msg); resolve(_msg);}, 2000);
});
}
function show2(msg) {
return new Promise(function(resolve){
console.log(msg);
resolve(msg);
});
}
var stack = [];
// add some function to stack
stack.push(function() { return show(1); });
stack.push(function() { return show(2); });
stack.push(function() { return show(3); });
stack.push(function() { return show2(4); });
stack.push(function() { return show(5); });
function* generator1() {
for(var key of stack) {
yield key();
}
}
var gen = generator1();
gen.next().value.then(function(){
gen.next().value.then(function(){
gen.next().value.then(function(){
gen.next().value.then(function(){
gen.next();
});
});
});
});
當然它看起來很難看,而且可以改進。 正如在另一個答案中提到的,有任務運行器和流控制庫,例如task.js , gen-run和co 。
有了co
,最后一部分將是:
co(generator1);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.