问题:有一段代码可能比较耗费时间,并且在等待其完成的时候,你不想阻塞其他的代码处理。但是,当耗时的函数完成的时候,你确实需要执行一些其他的功能
解决方案:将一个回调函数和setTimeout()结合使用,定时器设置为0.
function factorial(n){
console.log(n);
return n==1? 1:n*factorial(n-1);
}
function noBlock(n,callback){
setTimeout(function(){
var val = factorial(n);
if(callback && typeof callback =='function'){
callback(val);
}
}, 0);
}
console.log("Top of the morning to you");
noBlock(3,function(n){
console.log('first call ends with '+n);
noBlock(n,function(m){
console.log('final call ends with '+m);
});
});
var tst = 0;
for(i = 0;i<10;i++){
tst+=i;
}
console.log("value of tst is "+ tst);
noBlock(4,function(n){
console.log("end result is "+ n);
});
console.log("not doing too much");
//输出
"Top of the morning to you"
"value of tst is 45"
"not doing too much"
3
2
1
"first call ends with 6"
4
3
2
1
"end result is 24"
6
5
4
3
2
1
"final call ends with 720"
分析:
+ 原理:回调函数的意思就是一个函数作为参数传递给另一个函数,在某个条件下在函数内部调用传入的函数,或者在一个进程的末尾调用它。
+ 定时器事件会像其他异步事件一样,添加到事件队列的末尾而不是立马挤入到队列之中。通常,和定时器事件相关的任何功能,都是在同一个队列中的任何其他功能之后处理的。
+ 通过把setTimeout的定时器设置为 0 ,我们在解决方案中所作的,只是创建一个事件并将其放到执行队列的末尾。通过将耗时的事件放入到定时器的进程中,我们在等待进程完成的同时不再阻塞其他任务的进行。
+ 如上:先执行了主程序的三个console.log;队列中的下一个事件是 noBlock(3,function(6));接着是noBlock(4,function(24));然后是noBlock(6,720));