借鑒一道題:
代碼如下:
for(var i=0;i<5;i++){
setTimeout(function(){
console.info(new Date(),i);
},1000);
};
console.info(new Date(),i);
輸出結(jié)果是什么捉偏?
可以看出先打印出了一個(gè)5雷激,這是第六行代碼的輸出替蔬,然后間隔1s過后告私,同時(shí)打印出了5個(gè)5屎暇;即:5->5,5,5,5,5;
修改一
想要打印出5->1,2,3,4,5;的效果,如何修改代碼呢驻粟?
之所以會(huì)連續(xù)打印出5個(gè)5,是因?yàn)檠h(huán)體里的輸出語句是在1s過后才會(huì)加入執(zhí)行隊(duì)列根悼,這時(shí)“i”的值已經(jīng)變成了5;為了打印出1蜀撑,2挤巡,3,4酷麦,5矿卑;可以在每一次循環(huán)的時(shí)候立即執(zhí)行一個(gè)函數(shù),把當(dāng)前的“i”當(dāng)做參數(shù)傳入進(jìn)來沃饶,那么每次拿到的“i”就一樣了;
function outer(n){
setTimeout(function(){
console.info(new Date(),n);
},1000);
};
for(var i=0;i<5;i++){
outer(i);
};
console.info(new Date(),i);
修改二
先執(zhí)行循環(huán)體內(nèi)的輸出母廷,再執(zhí)行最外層的輸出;即先隔秒輸出0糊肤,1琴昆,2,3馆揉,4业舍;然后再輸出5;如何修改代碼呢升酣?
換種思路就是先執(zhí)行異步操作舷暮,再執(zhí)行同步代碼;與js原本的執(zhí)行順序正好是相反的噩茄。當(dāng)有明確的先后執(zhí)行順序時(shí)下面,可以利用promise來控制。
var tasks=[];
function task(n){
return new Promise(function(resolve,reject){
setTimeout(function(){console.info(new Date(),n);resolve();},n*1000)
});
};
for(var i=0;i<5;i++){
tasks.push(task(i));
};
Promise.all(tasks).then(function(){
setTimeout(function(){console.info(new Date(),i)},1000);
});
上面的面試題巢墅,只是提供了解決方法诸狭,而沒有講述javascript的運(yùn)行原理,下面就是本文的重點(diǎn):