setTimeout、Promise、Async/Await 的

2021-03-29  本文已影响0人  小杰66

MacroTask Queue

MacroTask Queue(宏任务队列)主要包括setTimeout, setInterval, setImmediate, requestAnimationFrame, UI rendeing, NodeJS中的`I/O等。

MicroTask Queue

MicroTask Queue(微任务队列)主要包括两类:
独立回调microTask:如Promise,其成功/失败回调函数相互独立;
复合回调microTask:如 Object.observe, MutationObserver 和NodeJs中的 process.nextTick ,不同状态回调在同一函数体;

MacroTask和MicroTask

1.依次执行同步代码直至执行完毕;
//这里JavaScript脚本执行也是一个macroTask,执行完毕后应该跳到第三步
2.检查MacroTask 队列,若有触发的异步任务,则取第一个并调用其事件处理函数,然后跳至第三步,若没有需处理的异步任务,则直接跳至第三步;
3.检查MicroTask队列,然后执行所有已触发的异步任务,依次执行事件处理函数,直至执行完毕,然后跳至第二步,若没有需处理的异步任务中,则直接返回第二步,依次执行后续步骤;
4.最后返回第二步,继续检查MacroTask队列,依次执行后续步骤;
5.如此往复,若所有异步任务处理完成,则结束;

process.nextTick

node中的process.nextTick方法可以在当前"执行栈"的尾部-下一次Event Loop(主线程读取"任务队列")之前----触发回调函数。也就是说,它指定的任务总是发生在所有异步任务之前。

console.log("start");
let promise1 = new Promise(function (resolve) {
  console.log("promise1");
  resolve();
  console.log("promise1 end");
}).then(function () {
  console.log("promise2");
});
setTimeout(function () {
  console.log("settimeout");
});
console.log("end");
//start -> promise1 ->promise1 end -> end -> promise2 -> settimeout

async function async1() {
  console.log("async1 start");
  await async2();
  console.log("async1 end");
}
async function async2() {
  console.log("async2");
}

console.log("start");
async1();
console.log("end");
//async方法执行时遇到await,await后表达式会立即执行,后面的代码会放入微任务(promise)
//start -> async1 start -> async2 -> end -> async1 end

var p1 = new Promise(function (resolve, reject) {
  console.log(1);
  resolve(1);
});
setTimeout(function () {
  console.log(2);
}, 0);
p1.then(function (value) {
  console.log(3);
});
setTimeout(function () {
  console.log(4);
}, 0);
// 1->3->2->4

setTimeout(function () {
  console.log("s1");
}, 0);
var p1 = new Promise(function (resolve, reject) {
  setTimeout(() => {
    console.log("s2");
    resolve(1);
  }, 0);
});
setTimeout(function () {
  console.log("s3");
}, 0);
for (var i = 0; i < 100; i++) {
  (function (j) {
    p1.then(function (value) {
      console.log("pt-" + j);
    });
  })(i);
}
// s1->s2->pt-0->...->pt-99->s3

async function async1() {
  console.log("async1 start");
  await async2();
  console.log("async1 end");
}
async function async2() {
  console.log("async2");
}
console.log("script start");
setTimeout(function () {
  console.log("setTimeout");
}, 0);
async1();
new Promise(function (resolve) {
  console.log("promise1");
  resolve();
}).then(function () {
  console.log("promise2");
});
console.log("script end");
//script start -> async1 start -> async2 -> promise1 -> script end -> async1 end -> promise2 -> setTimeout

console.log(1);
setTimeout(function () {
  console.log(2);
}, 0);
new Promise(function (resolve) {
  console.log(3);
  resolve(Date.now());
}).then(function () {
  console.log(4);
});
console.log(5);
setTimeout(function () {
  new Promise(function (resolve) {
    console.log(6);
    resolve(Date.now());
  }).then(function () {
    console.log(7);
  });
}, 0);
//1 3 5 4 2 6 7

console.log(1);
var start = Date.now();
setTimeout(function () {
  console.log(2);
}, 0);
setTimeout(function () {
  console.log(4, Date.now() - start);
}, 400);
Promise.resolve().then(function () {
  var sum = function (a, b) {
    return Number(a) + Number(b);
  };
  var res = [];
  for (var i = 0; i < 5000000; i++) {
    var a = Math.floor(Math.random() * 100);
    var b = Math.floor(Math.random() * 200);
    res.push(sum(a, b));
  }
  res = res.sort();
  console.log(3);
});
// 1 3 2 4

function A() {
  return Promise.resolve(Date.now());
}
async function B() {
  console.log(3);
  let now = await A();
  console.log(4);
}
console.log(1);
B();
console.log(2);
//1 3 2 4

console.log(1);
setTimeout(() => {
  console.log(4);
}, 0);
let promise = new Promise((resolve) => {
  console.log(3);
  resolve();
})
  .then((data) => {
    console.log(100);
  })
  .then((data) => {
    console.log(200);
  });
console.log(2);
//1 3 2 100 200 4

console.log(1);
setTimeout(() => {
  console.log(2);
  new Promise((resolve) => {
    console.log(4);
    resolve();
  }).then(() => {
    console.log(5);
  });
});
new Promise((resolve) => {
  console.log(7);
  resolve();
}).then(() => {
  console.log(8);
});
setTimeout(() => {
  console.log(9);
  new Promise((resolve) => {
    console.log(11);
    resolve();
  }).then(() => {
    console.log(12);
  });
});
//1 7 8 2 4 5 9 11 12

console.log(1);
setTimeout(() => {
  console.log(2);
  new Promise((resolve) => {
    console.log(4);
    resolve();
  }).then(() => {
    console.log(5);
  });
  process.nextTick(() => {
    console.log(3);
  });
});
new Promise((resolve) => {
  console.log(7);
  resolve();
}).then(() => {
  console.log(8);
});
process.nextTick(() => {
  console.log(6);
});
// 1 7 6 8 2 4 3 5

console.log(1);
setTimeout(() => {
  console.log(2);
  new Promise((resolve) => {
    console.log(4);
    resolve();
  }).then(() => {
    console.log(5);
  });
  process.nextTick(() => {
    console.log(3);
  });
});
new Promise((resolve) => {
  console.log(7);
  resolve();
}).then(() => {
  console.log(8);
});
process.nextTick(() => {
  console.log(6);
});
setTimeout(() => {
  console.log(9);
  process.nextTick(() => {
    console.log(10);
  });
  new Promise((resolve) => {
    console.log(11);
    resolve();
  }).then(() => {
    console.log(12);
  });
});

//1 7 6 8 2 4 3 5 9 11 10 12

参考链接:
https://juejin.cn/post/6844903655473152008
http://www.ruanyifeng.com/blog/2014/10/event-loop.html

上一篇下一篇

猜你喜欢

热点阅读