我在for循环中面临一个事件监听器的问题。
基本上我有这个:
for (var i = 0; i < 2; i++) {
//window url change here, each iteration open a different url
console.log('what??');
window.addEventListener('load', aperture, true);
function aperture() {
console.log('here');
window.close();
}
}
所以,我必须等待窗口加载才能执行该函数,然后转到下一步进行迭代并执行相同的操作。但是我看到这个日志的原因是:
what??
what??
here
here
如何在迭代之间等待事件监听器完成?
答案 0 :(得分:0)
我只会回答你实际问过的问题......
如何在迭代之间等待事件监听器完成?
你不能用真正的循环来实现它,制作异步“循环”的唯一方法是使用递归,这可能会稍微复杂一些。我们的想法是创建一个函数,在它准备好再次迭代时调用它自己。
(function myLoop(){
// do something that takes a while
setTimeout(function(){
console.log("did something");
// then recurse...
myLoop();
}, 1500);
})();
如果你在一个数组上循环,那么这个概念是类似的...这是我写的general purpose function做的事情......
var myArray = ["a","b","c","d"];
var myLoop = slowLoop(myArray, (itm, idx, cb)=>{
setTimeout(()=>{
console.log(`doing something with ${itm} which is item number ${idx} in the array`);
// call cb when finished
cb();
}, 1000);
});
// when it's done....
myLoop.then(()=>{
console.log("All done looping");
});
/**
* Execute the loopBody function once for each item in the items array,
* waiting for the done function (which is passed into the loopBody function)
* to be called before proceeding to the next item in the array.
* @param {Array} items - The array of items to iterate through
* @param {Function} loopBody - A function to execute on each item in the array.
* This function is passed 3 arguments -
* 1. The item in the current iteration,
* 2. The index of the item in the array,
* 3. A function to be called when the iteration may continue.
* @returns {Promise} - A promise that is resolved when all the items in the
* in the array have been iterated through.
*/
function slowLoop(items, loopBody) {
return new Promise(f => {
done = arguments[2] || f;
idx = arguments[3] || 0;
let cb = items[idx + 1] ? () => slowLoop(items, loopBody, done, idx + 1) : done;
loopBody(items[idx], idx, cb);
});
}