ES6迭代器和settimeout

时间:2018-02-25 13:55:44

标签: javascript ecmascript-6 es6-promise

我正在尝试迭代请求列表,但在处理下一个请求之前有一段延迟。我想使用ES6 Iterator进行如下操作,但它不起作用...(控制台输出为我冻结,不知道为什么)

requests = [1,2,3,4,5,6];
delay    = 2000;

const iterateCollection = requests => {
return new Promise((resolve, reject) => {

    function *iterateRequests() {
        for (const req of requests) {
            yield req;
        }
    }

    const requestIterator = iterateRequests();
    let   currentRequest  = requestIterator.next();

    while(!currentRequest.done) {
        setTimeout(() => { 
            console.log(currentRequest);
            currentRequest = requestIterator.next();
        }, delay);
    }

    resolve();
}); 
};

iterateCollection(requests)
    .then(() => console.log('done!'));

似乎没有喜欢setTimeOut。如果我从代码中删除它(删除延迟),我得到预期的迭代没有延迟,如此..

requests = [1,2,3,4,5,6];
delay    = 2000;

const iterateCollection = requests => {
  return new Promise((resolve, reject) => {

    function *iterateRequests() {
        for (const req of requests) {
            yield req;
        }
    }

    const requestIterator = iterateRequests();
    let   currentRequest  = requestIterator.next();

    while(!currentRequest.done) {
        console.log(currentRequest);
        currentRequest = requestIterator.next();
    }

    resolve();
  });   
};

iterateCollection(requests)
    .then(() => console.log('done!'));

// OUTPUT
//{value: 1, done: false}
//VM85:26 {value: 2, done: false}
//VM85:26 {value: 3, done: false}
//VM85:26 {value: 4, done: false}
//VM85:26 {value: 5, done: false}
//VM85:26 {value: 6, done: false}
//VM85:35 done!

1 个答案:

答案 0 :(得分:2)

异步事件在所谓的事件队列中排队,直到js引擎完成当前任务,然后它从事件队列中接受下一个任务。在您的情况下,当前任务是:

while(!currentRequest.done) {

由于您的数组有一个元素,迭代器没有完成,循环将永远运行。所有超时都停留在事件队列中,处理程序将永远不会执行。您可以只使用async,这样您就可以等待循环,直到超时完成:

 const timer = ms => new Promise(res => setTimeout(res, ms));

async function iterateCollection(collection){
  for(const el of collection){
    await timer(1000);
     //...
  }
}