1. 程式人生 > 實用技巧 >JavaScript 關於閉包、同步、非同步問題

JavaScript 關於閉包、同步、非同步問題

for (var i = 0; i < 5; i++){
     setTimeout(function(){
          console.log(new Date, i)
     }, 1000);
}
console.log(new Date, " -> ", i)

同步,非同步,變數作用域,閉包。
如果規定用箭頭表示前後兩次輸出之間有1秒的間隔,而逗號表示其前後兩次輸出之間的間隔可以忽略
5 -> 5,5,5,5,5

  1. 如果想輸出5, 0, 1, 2, 3, 4
// 方法1:JS中基礎型別的引數傳遞是按值傳遞
var output = function(i) {
     setTimeout(function() {
          console.log(new Date, i)
     }, 1000)
}

for (var i = 0; i < 5; i++){
     output(i)
}

console.log(new Date, i)

// 方法2:IFEE宣告即執行的函式表示式
for (var i = 0; i < 5; i++) {
     (function(j){
          setTimeout(function(){
               console.log(new Date, j)
          }, 1000);
     })(i);
}
console.log(new Date, i)
  1. 順序輸出數字
const tasks = [];
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);
});

//方法2 ES7 async await TODO:失敗
const sleep = (timeoutMS) => new Promise((resolve) =>{
     setTimeout(resolve, timeoutMS);
})
(async () =>{
     for (var i = 0; i < 5; i++) {
          await sleep(1000);
          console.log(new Date, i);
     }
     await sleep(1000);
     console.log(new Date, i);
})();