廢話不多說竟稳,這次直接上干貨——
-代碼走起
// //源碼
for(var i=0;i<5;i++){
setTimeout(function() {
console.log(new Date,i)
}, 1000);
}
console.log(new Date,i);
// // 結果:
// // Mon Mar 20 2017 10:30:56 GMT+0800 (中國標準時間) 5
// // Mon Mar 20 2017 10:30:57 GMT+0800 (中國標準時間) 5
// // Mon Mar 20 2017 10:30:57 GMT+0800 (中國標準時間) 5
// // Mon Mar 20 2017 10:30:57 GMT+0800 (中國標準時間) 5
// // Mon Mar 20 2017 10:30:57 GMT+0800 (中國標準時間) 5
// // Mon Mar 20 2017 10:30:57 GMT+0800 (中國標準時間) 5
//變形1-1
//變形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)結束后在大概第 5 秒的時候輸出 ,只能說大概
//變形2-2
//重新思考這個問題晤碘,
//如果把這次的需求抽象為:
//在系列異步操作完成(每次循環(huán)都產(chǎn)生了 1 個異步操作)之后褂微,
//再做其他的事情功蜓,代碼該怎么組織?
//對宠蚂,就是 Promise式撼。
const tasks = [];
for (var i = 0; i < 5; i++) {
((j) => {
tasks.push(new Promise((resolve) => {
setTimeout(() => {
console.log(new Date, j);
resolve();// 這里一定要 resolve,否則代碼不會按預期 work
}, 1000 * j); // 定時器的超時時間逐步增加
}));
})(i);
}
Promise.all(tasks).then(() => {
setTimeout(() => {
console.log(new Date, i);
}, 1000); // 注意這里只需要把超時設置為 1 秒
});
//變形2-3
//努力使代碼閱讀時的顆粒度更小求厕,模塊化更好
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 處理異步代碼比回調機制讓代碼可讀性更高,
//但是使用 Promise 的問題也很明顯呀癣,
//即如果沒有處理 Promise 的 reject美浦,會導致錯誤被丟進黑洞,
//好在新版的 Chrome 和 Node 7.x 能對未處理的異常
//給出 Unhandled Rejection Warning项栏,
//而排查這些錯誤還需要一些特別的技巧(瀏覽器浦辨、Node.js)。
//變形2-4
//既然 Promise 已經(jīng)被拿下沼沈,
//如何使用 ES7 中的 async await 特性來讓這段代碼變的更簡潔流酬?
// 模擬其他語言中的 sleep,實際上可以是任何異步操作
const sleep = (timeountMS) => new Promise((resolve) => {
setTimeout(resolve, timeountMS);
});
(async () => { // 聲明即執(zhí)行的 async 函數(shù)表達式
for (var i = 0; i < 5; i++) {
await sleep(1000);
console.log(new Date, i);
}
await sleep(1000);
console.log(new Date, i);
})();