javascript队列函数与异步执行详细解决方案
假设你有几个功能FN1、FN2、FN3,需要为了所谓的。当然,最简单的方法是:
(FN1);
(FN2);
(3);
但有时这些函数是一个接一个地添加操作的,调用的时间不知道什么功能;此时您可以预先定义一个数组,当在推送中添加一个函数时,当您需要从数组中取出一个接一个的函数,以便调用:
var堆栈{ };
/ /执行其他操作的定义,FN1
Stack.push(FN1);
/ /执行其他操作的定义,FN2、FN3
Stack.push(FN2、FN3);
呼叫/时间
stack.foreach(功能(Fn){ fn()});
这样的函数没有名称,也不重要,它可以直接通过匿名函数进行测试:
var堆栈{ };
功能FN1(){
console.log(第一个电话);
}
Stack.push(FN1);
功能Fn2(){
console.log(第二电话);
}
Stack.push(FN2,函数(){ console.log(‘三称)});
stack.foreach(功能(Fn){(FN)}); / /输出序列的第一个电话和第二呼叫和第三电话
这个实现通常工作到目前为止,但是我们忽略了一个例子,异步函数的调用。这里不讨论Javascript中异步的各种术语和概念。请自己读(例如,一个著名的注释)。如果你知道下面的代码将输出1, 3和2,继续往下看:
(1)console.log;
setTimeout(){()函数(
(2)console.log;
},0);
(3)console.log;
如果堆栈队列具有类似的函数函数是异步的,那么我们的实现就会一团糟:
var堆栈{ };
功能FN1(){ console.log(第一个电话)};
Stack.push(FN1);
功能Fn2(){
setTimeout(function(){ fn2timeout)
console.log(第二电话);
},0);
}
Stack.push(FN2,函数(){ console.log(‘三称)});
stack.foreach(功能(Fn){(FN)}); / /输出的第一个电话和第三电话和第二呼叫
显然,FN2是为了呼吁,但是setTimeout(fn2timeout){ console.log(第二呼叫)}不立即执行(即使超时设置为0 FN2);调用后立即返回,然后FN3实施、FN3执行这真的是fn2timeout后。
如何解决在我们的分析中,这里的关键是fn2timeout,我们要等到它真的结束了叫FN3,理想像这样:
功能Fn2(){
setTimeout(){()函数(
fn2timeout();
(3);
},0);
}
但这是相当于一个新的函数代替原来的fn2timeout,插入原fn2timeout和FN3进去。这对原函数的动态版本有一个专用的名词叫猴子补丁。根据我们的程序员的口头禅:这是一定要做的,但它是一个小拧和容易去。有没有更好的办法吗
我们退一步,我们没有强制执行的fn2timeout FN3完全在fn2timeout函数体的最后一行被称为。
功能Fn2(){
setTimeout(function(){ fn2timeout)
console.log(第二电话);
FN3({ 1 }); / /注
},0);
}
它看起来好一点,但没有FN3当你定义FN2、FN3,是吗
另一个问题是,在FN2,如果你想打电话给FN3,我们不能通过电话stack.foreach FN3,否则FN3将重复调用两次。
我们不能在FN2写FN3。相反,我们只需要在fn2timeout最终找到堆栈氮气分压下功能,又叫它:
功能Fn2(){
setTimeout(function(){ fn2timeout)
console.log(第二电话);
下一步();
},0);
}
下一个函数负责查找堆栈中的下一个函数并执行它:
var指数= 0;
函数下一步(){
堆栈= { };
索引= 1;事实上,也可以使用移位来连接
如果(类)FN(FN = 'function);
}
下一步得到堆栈中的函数,{ },每次调用一次,索引增加1,以达到提取下一个函数的目的。
下一个使用这个:
var堆栈{ };
索引的定义和下一步
功能FN1(){
console.log(第一个电话);
(下一步);每个堆栈函数必须称为下一个。
};
Stack.push(FN1);
功能Fn2(){
setTimeout(function(){ fn2timeout)
console.log(第二电话);
下一步(下一步);
},0);
}
Stack.push(FN2,函数(){(){
console.log(‘三通话);
(下一步);最后一个不能调用,调用也无用。
});
下一个(下一个)调用;最终输出序列第一次调用和第二次调用和第三调用。
现在stack.foreach线已被删除。我们下一次打电话。我们会发现第一个函数在执行堆栈,FN1,FN1要求下,找到下一个功能Fn2并执行它,然后再调用FN2,等等。下一个
每个函数都必须调用下一个函数。如果一个函数没有被写入,程序将在函数执行后直接结束,并且没有机制继续。
在了解函数队列的实现之后,您应该能够解决下面的面试问题:
/ /傻大锅的实现,可以称为以下方式:
LazyMan(Hank)
输出:
你好!我是Hank。
* /
LazyMan(Hank),睡眠(10)吃(晚餐)输出。
输出:
你好!我是Hank。
等待10秒。
10点后醒来
吃晚饭~
* /
LazyMan(Hank)。吃(晚餐)吃(晚餐)。
输出:
你好,我是Hank!
吃晚饭~
吃晚饭~
* /
LazyMan(Hank)。SleepFirst(5)吃(晚餐)。
继续等待5秒,输出
5点后醒来
你好,我是Hank!
吃晚饭
* /
等。
著名的连接框架在Node.js正是中间件队列实现。有趣的是看它的源代码或这样解释什么是连接中间件。
您可能会注意到,下一步只能暂时放在函数的结尾处。如果你把它放在中间,原来的问题就会出现。
函数FN(){
(1)console.log;
下一步();
console.log(2)(下); / /如果调用异步函数,console.log(2)将首先执行
}
Redux和KOA可以通过不同的实现放在函数中。在执行后面部分的功能之后,下一次执行代码将非常聪明。接下来是代码。有时间再写和写。
以上是本文的全部内容,希望能对您有所帮助,希望大家多多支持。