为什么功能的运行顺序,即使它们被异步循环中调用?

时间:2019-02-01 09:19:07

标签: javascript loops asynchronous closures settimeout

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

预期输出:

  

嗨,我刻不容缓

     

你好,我迟到了

但实际输出是:

  

你好,我迟到了

     

嗨,我刻不容缓

2 个答案:

答案 0 :(得分:1)

JS在单个线程上运行,您的函数将不会并行运行。一次只能运行一个。由于您已将fnArr数组vi中的第一个功能安排为具有0个延迟的两个功能。 withDelay将首先运行。仅当这将完成其执行时,第二个功能withoutDelay才会开始执行。 setTimeout将无法保证在提供的间隔后执行,这是函数执行的最小间隔。可以进一步了解setTimeout here

答案 1 :(得分: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);