【问题标题】:Why functionalities runs sequentially even though they are being called asynchronously inside a loop?为什么功能顺序运行,即使它们在循环内被异步调用?
【发布时间】:2019-06-25 20:18:51
【问题描述】:

我正在创建一个包装函数,它将采用函数数组并以并行方式执行每个函数,因此考虑使用 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)
}

预期输出:

嗨,我马上就来

你好,我来晚了

但实际输出是:

你好,我来晚了

嗨,我马上就来

【问题讨论】:

  • quora.com/… 尝试阅读此内容,浏览器将异步调用推送到队列中。因此这种顺序行为
  • while 函数内部的 withDelay 循环会冻结浏览器,然后这两个函数都会运行。而且由于您在fnArr 中指定的顺序,withDelay 将首先开火。

标签: javascript loops asynchronous closures settimeout


【解决方案1】:

虽然循环不会延迟您需要在 withDelay() 中使用 setTimeout 的函数,但它工作正常

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);

【讨论】:

  • 但它不再具有阻塞功能。这只是推迟事情。我可能在队列(数组)中有任何类型的函数要执行。
  • @kish 我已经更新了答案。是显示在队列中运行具有时间延迟的函数数组的示例。使用Promisesasync await。满意就采纳答案
【解决方案2】:

JS 在单线程上运行,您的函数不会并行运行。它一次只会运行一个。由于您已将这两个函数安排为延迟为 0 的第一个函数来自 fnArr 数组即。 withDelay 将首先运行。只有当它完成执行时,第二个函数withoutDelay 才会开始执行。 setTimeout 将不保证您在提供的时间间隔后执行,这是您的函数将执行的最小时间间隔。你可以阅读更多关于setTimeouthere

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 1970-01-01
    • 2016-06-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-18
    相关资源
    最近更新 更多