Javascript ES6 生成器异步
Javascript ES6 generator async
我需要 运行 生成器异步(我需要在控制台 1、2、3、4、5 中得到结果,因为现在我有 4、1、2、3、5)任何人都可以提供帮助我?我需要 运行 个任务,并在上一个任务完成后等待 运行 下一个任务。我需要使用(如果可能:仅)生成器(或生成器 + promise?)
这是我的代码
/*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();
有很多 "task running" 函数,您甚至可以编写自己的函数。但是你必须为此使用 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/为此专门提供了一个函数
希望对您有所帮助!
这完全可以用发电机来完成。这是一种方法的示例,我们将 .next()
移到超时本身中,以确保它不会提前发生。此外,生成器现在 returns 函数离开堆栈而不是执行它,因为您无法从生成器本身的执行中调用生成器上的 .next()
。
这里值得注意的是,这可能不是我执行此操作的方式 'in the wild';我会包括承诺。但是你问是否可以只用一个生成器来完成 - 答案是 'yes'.
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 是解决该问题的好方法。
我会尽可能坚持你的原始代码:
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, and co.
对于 co
,最后一部分将是:
co(generator1);
我需要 运行 生成器异步(我需要在控制台 1、2、3、4、5 中得到结果,因为现在我有 4、1、2、3、5)任何人都可以提供帮助我?我需要 运行 个任务,并在上一个任务完成后等待 运行 下一个任务。我需要使用(如果可能:仅)生成器(或生成器 + promise?)
这是我的代码
/*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();
有很多 "task running" 函数,您甚至可以编写自己的函数。但是你必须为此使用 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/为此专门提供了一个函数
希望对您有所帮助!
这完全可以用发电机来完成。这是一种方法的示例,我们将 .next()
移到超时本身中,以确保它不会提前发生。此外,生成器现在 returns 函数离开堆栈而不是执行它,因为您无法从生成器本身的执行中调用生成器上的 .next()
。
这里值得注意的是,这可能不是我执行此操作的方式 'in the wild';我会包括承诺。但是你问是否可以只用一个生成器来完成 - 答案是 'yes'.
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 是解决该问题的好方法。
我会尽可能坚持你的原始代码:
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, and co.
对于 co
,最后一部分将是:
co(generator1);