Javascript ES6生成器异步

Javascript ES6生成器异步,javascript,generator,ecmascript-6,Javascript,Generator,Ecmascript 6,我需要运行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); }

我需要运行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();
有很多“任务运行”函数,你甚至可以自己编写。但是您必须为此使用承诺,而不是
setTimeout
。下面是一个简单的例子:

功能延迟(ms,val){
返回新承诺(功能(res){
setTimeout(res,ms | | | 1000,val | | Math.random());
});
}
函数*运行(){
屈服延迟();
log(屈服延迟());
屈服延迟();
console.log('foo');//在两者之间的任意位置同步调用
log(屈服延迟());
}
函数异步(gen){“使用严格”;
gen=gen();
返回Promise.resolve().then(函数cont(a){
var n=下一代发电机(a),
v=承诺。解决(n.值);
if(n.done)返回v;//a`return`
返回n.value.catch(gen.throw.bind(gen)),然后返回(cont);
});
};

异步(运行)这完全可以用生成器完成。下面是一种方法的示例,在这种方法中,我们将
.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();

您需要一种方法让您的函数知道它们何时完成。承诺是解决这个问题的好办法

我将尽可能地坚持您的原始代码:

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();
        });
    });
  });
});
当然,它看起来很难看,而且可以改进。正如在另一个答案中提到的,有任务运行程序和流控制库,例如,和

对于
co
,最后一部分是:

co(generator1); 

首先尝试编写一个没有生成器的解决方案(只使用回调或承诺)。然后,我们可能会向您展示如何将生成器合并到该图中,因为生成器本身并不是异步的