提问人:kish 提问时间:2/1/2019 更新时间:2/1/2019 访问量:35
为什么函数按顺序运行,即使它们在循环中异步调用?
Why functionalities runs sequentially even though they are being called asynchronously inside a loop?
问:
我正在创建一个包装函数,它将采用函数数组并以并行方式执行每个函数,因此考虑使用 setTimeout,但函数仍然按顺序运行。我怀疑这可能是因为用于调用 SetTimeout 的闭包。但是,既然 setTimeout 无论如何都是异步的,为什么这很重要呢?
// some blocking functionality
var withDelay = function (a) {
var currentTime = new Date().getTime(), delay = 5000;
while (currentTime + delay >= new Date().getTime()) {
}
console.log(a+"I am with delay");
}
// some non blocking functionality
var withoutDelay = function(a) {
console.log(a+"I am with no delay");
}
var fnArr = [withDelay, withoutDelay]; //array of functions
var args = ["Hi,"]; // arbitrary params
for( var i=0; i < fnArr.length; i++) {
var fn = fnArr[i];
(function(f,arg) {
return setTimeout(function(){ return f.apply(f,arg) },0);
})(fn,args)
}
预期输出:
嗨,我没有耽搁
嗨,我有延迟
但实际输出为:
嗨,我有延迟
嗨,我没有耽搁
答:
1赞
Ashish
2/1/2019
#1
JS 运行在单个线程上,您的函数不会并行运行。它一次只能运行一个。由于您已经将两个函数都调度为 0 延迟,因此数组中的第一个函数即。 将首先运行。只有当这完成其执行时,第二个函数才会开始执行。 不保证您在提供的时间间隔后执行,这是您的函数将执行的最小时间间隔。你可以在这里阅读更多关于这里的信息fnArr
withDelay
withoutDelay
setTimeout
setTimeout
1赞
Maheer Ali
2/1/2019
#2
虽然循环不会延迟函数,但您需要在 set Timeout 中使用 setTimeout,它工作正常withDelay()
var withDelay = function (a) {
setTimeout(() => {console.log(a+"I am with delay")},5000);
}
// some non blocking functionality
var withoutDelay = function(a) {
console.log(a+"I am with no delay");
}
var fnArr = [withDelay, withoutDelay]; //array of functions
var args = ["Hi,"]; // arbitrary params
for( var i=0; i < fnArr.length; i++) {
var fn = fnArr[i];
(function(f,arg) {
return setTimeout(function(){ return f.apply(f,arg) },0);
})(fn,args)
}
function func1(){
console.log("Function 1 is executed");
console.timeEnd('t');
}
function func2(){
console.log("Function 2 is executed");
console.timeEnd('t');
}
function func3(){
console.log("Function 3 is executed");
console.timeEnd('t');
}
let arrr = [
{func:func1,delay:2000},
{func:func2,delay:2000},
{func:func3,delay:3000},
]
async function callWithDelay(funcArr){
for(let func of funcArr){
//just to see time in console not necesarry
console.time('t');
//create a promise
let promise = new Promise((resolve,reject) => {
//'promise' will resolve after the function inside following code will end
setTimeout(()=>
{
resolve();
func.func();
},func.delay)
})
//The code will not proceed until the 'promise' is resolved(func is excecuted);
let x = await promise;
}
console.log("All the functions are excecuted");
}
callWithDelay(arrr);
评论
0赞
kish
2/1/2019
但随后它就不再具有阻止功能了。它只是推迟事情。我可能在队列(数组)中有任何类型的函数来执行。
0赞
Maheer Ali
2/1/2019
@kish我已经更新了答案。显示了在队列中运行具有时间延迟的函数数组的示例。使用 和 。如果您满意,请接受答案Promises
async await
评论
while
withDelay
fnArr
withDelay