控制.each循环nodejs内的执行流程

时间:2016-07-08 11:12:45

标签: javascript node.js ecmascript-6 generator

我正在尝试使用生成器停止setTimeOut上的执行流程。我究竟做错了什么?我不能每1500毫秒获得console.log。我是节点上的新手,如果我做的很蠢,请不要心灵感应地杀了我

['1', '2', '3'].forEach(function* iteration(index) {
  // Some logic here
  yield setTimeout(() => console.log('sick of this!'), 1500)
  iteration.next(index)
})

2 个答案:

答案 0 :(得分:1)

可悲的是你不能。 Array.prototype.forEach是一个更高级别的函数,它只调用给定的回调函数,但不会也不能生成生成器。我的意思是你可以给一个生成器,因为生成器只是正常的函数,但它们不会运行,你也不能产生值。

第二件事是你只会产生timeoutId-s,我很确定你想要等待1500毫秒。

所以你必须摆脱forEach并使用for..of代替,并且必须编写一个延迟函数,使用async / await它看起来像:

function delay(time, value) {
  return new Promise(resolve => { setTimeout(() => { resolve(value); }, time); });
}

async function main() {
  for (var item of ['1', '2', '3']) {
    await delay(1000);
    console.log(item);
  }
}

main().then(null, e => console.error(e));

You can transpile it with babel.

如果你想使用常规节点回调,这有点难,不太好,但绝对可能。如果您被允许选择,我建议您使用async / await方式。

答案 1 :(得分:0)

可能你可以这样做;

['1', '2', '3'].forEach(e => { function *iteration(index) {
                                 // Some logic here
                                 var val = yield setTimeout(_ => it.next(index),0); // make async
                                 setTimeout(_ => console.log('sick of this..! '+ val), 1500*val);
                               }
                               var it = iteration(e);
                               it.next(); // start the engine
                             });

或建议通过ES6承诺作业队列异步

['1', '2', '3'].forEach(e => {function *iteration(index) {
                                // Some logic here
                                var val = yield Promise.resolve(index).then(v => it.next(v)); // async by the job queue
                                setTimeout(_ => console.log('sick of this..! '+ val), 1500*val);
                              }
                              var it = iteration(e);
                              it.next(); // start the engine
                             });