Почему функциональные возможности выполняются последовательно, даже если они вызываются асинхронно внутри цикла? - PullRequest
0 голосов
/ 01 февраля 2019

Я создаю функцию-обертку, которая принимает массив функций и выполняет каждую функцию параллельно, поэтому подумал об использовании 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 голосов
/ 01 февраля 2019

Хотя цикл не задерживает функцию, вам нужно использовать 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 голосов
/ 01 февраля 2019

JS работает в одном потоке, Ваша функция не будет работать параллельно.Он будет работать только по одному за раз.Поскольку вы запланировали обе функции с задержкой 0, как только первая функция из массива fnArr, а именно.withDelay будет работать первым.Только когда это завершит выполнение, вторая функция withoutDelay начнет выполнение.setTimeout не гарантирует вашего выполнения после указанного интервала, это минимальный интервал, после которого ваша функция будет выполняться.Вы можете узнать больше о setTimeout здесь

...