// //源碼
for(var i=0;i<5;i++){
setTimeout(function() {
console.log(new Date,i)
}, 1000);
}
console.log(new Date,i);
// // 結(jié)果:
// // Mon Mar 20 2017 10:30:56 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間) 5
// // Mon Mar 20 2017 10:30:57 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間) 5
// // Mon Mar 20 2017 10:30:57 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間) 5
// // Mon Mar 20 2017 10:30:57 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間) 5
// // Mon Mar 20 2017 10:30:57 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間) 5
// // Mon Mar 20 2017 10:30:57 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間) 5
//變形1-1
for(var i=0;i<5;i++){
(function(index){
setTimeout(function(){
console.log(new Date,index);
},1000)
})(i)
}
console.log(new Date,i);
// //結(jié)果:
// // Mon Mar 20 2017 10:30:56 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間) 5
// // Mon Mar 20 2017 10:30:57 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間) 0
// // Mon Mar 20 2017 10:30:57 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間) 1
// // Mon Mar 20 2017 10:30:57 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間) 2
// // Mon Mar 20 2017 10:30:57 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間) 3
// // Mon Mar 20 2017 10:30:57 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間) 4
//變形1-2
//定義一個(gè)幫助函數(shù),利用 JS 中基本類型(Primitive Type)的參數(shù)傳遞是
//按值傳遞(Pass by Value)的特征浅缸;
//這樣的做法顯然是更符合直覺(jué)的
var helper=function(index){
setTimeout(function(){
console.log(new Date,index);
},1000)
};
for(var i=0;i<5;i++){
helper(i);// 這里傳過(guò)去的 i 值被復(fù)制了
}
console.log(new Date,i);
for(var i=0;i<5;i++){
var helper=function(index){
setTimeout(function(){
console.log(new Date,index);
},1000)
};
helper(i);// 這里傳過(guò)去的 i 值被復(fù)制了
}
console.log(new Date,i);
//變形1-3
//這里只有個(gè)非常細(xì)微的變動(dòng)姑荷,即使用 ES6 塊級(jí)作用域(Block Scope)中的 let 替代了 var荸百,
//但是代碼在實(shí)際運(yùn)行時(shí)會(huì)報(bào)錯(cuò)禽笑,
//因?yàn)樽詈竽莻€(gè)輸出使用的 i ,
//在其所在的作用域中并不存在百姓,i 只存在于循環(huán)內(nèi)部赫编。
for(let i=0;i<5;i++){
setTimeout(function(){
console.log(new Date,i);
},1000)
}
console.log(new Date,i);//最后輸出使用的 i 不存在,會(huì)報(bào)錯(cuò)
//結(jié)果:
//Uncaught ReferenceError: i is not defined at....
//Mon Mar 20 2017 10:48:09 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間) 0
//Mon Mar 20 2017 10:48:09 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間) 1
//Mon Mar 20 2017 10:48:09 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間) 2
//Mon Mar 20 2017 10:48:09 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間) 3
//Mon Mar 20 2017 10:48:09 GMT+0800 (中國(guó)標(biāo)準(zhǔn)時(shí)間) 4
//變形2-1
//期望代碼的輸出變成 0 -> 1 -> 2 -> 3 -> 4 -> 5拄衰,
//并且要求原有的代碼塊中的循環(huán)和兩處 console.log 不變蛤奢,
//該怎么改造代碼鬼癣?
for(var i=0;i<5;i++){
(function(index){
setTimeout(function(){
console.log(new Date,index);
},1000)
})(i)
}
setTimeout(function(){
console.log(new Date,i);
},1000*i)//循環(huán)結(jié)束后在大概第 5 秒的時(shí)候輸出 ,只能說(shuō)大概
//變形2-2
//重新思考這個(gè)問(wèn)題,
//如果把這次的需求抽象為:
//在系列異步操作完成(每次循環(huán)都產(chǎn)生了 1 個(gè)異步操作)之后啤贩,
//再做其他的事情待秃,代碼該怎么組織?
//對(duì)痹屹,就是 Promise章郁。
const tasks = [];
for (var i = 0; i < 5; i++) {
((j) => {
tasks.push(new Promise((resolve) => {
setTimeout(() => {
console.log(new Date, j);
resolve();// 這里一定要 resolve,否則代碼不會(huì)按預(yù)期 work
}, 1000 * j); // 定時(shí)器的超時(shí)時(shí)間逐步增加
}));
})(i);
}
Promise.all(tasks).then(() => {
setTimeout(() => {
console.log(new Date, i);
}, 1000); // 注意這里只需要把超時(shí)設(shè)置為 1 秒
});
//變形2-3
//努力使代碼閱讀時(shí)的顆粒度更小志衍,模塊化更好
const tasks = []; // 這里存放異步操作的 Promise
const output = (i) => new Promise((resolve) => {
setTimeout(() => {
console.log(new Date, i);
resolve();
}, 1000 * i);
});
// 生成全部的異步操作
for (var i = 0; i < 5; i++) {
tasks.push(output(i));
}
// 異步操作完成之后暖庄,輸出最后的 i
Promise.all(tasks).then(() => {
setTimeout(() => {
console.log(new Date, i);
}, 1000);
});
//注意:
//使用 Promise 處理異步代碼比回調(diào)機(jī)制讓代碼可讀性更高,
//但是使用 Promise 的問(wèn)題也很明顯楼肪,
//即如果沒(méi)有處理 Promise 的 reject培廓,會(huì)導(dǎo)致錯(cuò)誤被丟進(jìn)黑洞,
//好在新版的 Chrome 和 Node 7.x 能對(duì)未處理的異常
//給出 Unhandled Rejection Warning春叫,
//而排查這些錯(cuò)誤還需要一些特別的技巧(瀏覽器医舆、Node.js)。
//變形2-4
//既然 Promise 已經(jīng)被拿下象缀,
//如何使用 ES7 中的 async await 特性來(lái)讓這段代碼變的更簡(jiǎn)潔蔬将?
// 模擬其他語(yǔ)言中的 sleep,實(shí)際上可以是任何異步操作
const sleep = (timeountMS) => new Promise((resolve) => {
setTimeout(resolve, timeountMS);
});
(async () => { // 聲明即執(zhí)行的 async 函數(shù)表達(dá)式
for (var i = 0; i < 5; i++) {
await sleep(1000);
console.log(new Date, i);
}
await sleep(1000);
console.log(new Date, i);
})();
最后編輯于 :
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者