事件循环

JS为单线程
宏任务主要包含:script( 整体代码)、setTimeout、setInterval、I/O、UI 交互事件、setImmediate(Node.js 环境)

微任务主要包含:Promise、MutaionObserver、process.nextTick(Node.js 环境)

例子1

console.log('script start');

setTimeout(function() {
  console.log('timeout1');
}, 10);

new Promise(resolve => {
    console.log('promise1');
    resolve();
    setTimeout(() => console.log('timeout2'), 10);
}).then(function() {
    console.log('then1')
})

console.log('script end');


先执行第一个log

setTimeout推入宏队列hong1

遇到promise马上执行打印然后将它所有的then推入微队列后把setTimeout推入宏队列hong2

先执行微队列,所以先打印then里面的。然后宏队列再打印






例子2

  console.log('1');

setTimeout(function() {
    console.log('2');
  
    new Promise(function(resolve) {
        console.log('4');
        resolve();
    }).then(function() {
        console.log('5')
    })
})

new Promise(function(resolve) {
    console.log('7');
    resolve();
}).then(function() {
    console.log('8')
})

setTimeout(function() {
    console.log('9');
   
    new Promise(function(resolve) {
        console.log('11');
        resolve();
    }).then(function() {
        console.log('12')
    })
})


当在只剩两个宏任务的setTimeout时候执行第一个时,Promise压入了then的微任务,让第二个宏任务又排到微任务后等待


async和await

  1. await后面接一个会return new promise的函数并执行它
  2. await只能放在async函数里
function 摇色子(){
    return new Promise((resolve, reject)=>{
        let sino = parseInt(Math.random() * 6 +1)
        setTimeout(()=>{
            resolve(sino)
        },3000)
    })
}
async function test(){
    let n =await 摇色子()
    console.log(n)
}
test()
  • async函数会返回一个promise,并且Promise对象的状态值是resolved(成功的)
    • 如果你没有在async函数中写return,那么Promise对象resolve的值就是是undefined
    • 如果你写了return,那么return的值就会作为你成功的时候传入的值

await 等到之后,做了一件什么事情?

  • 不是promise对象
  • 是promise对象

如果不是 promise , await会阻塞后面的代码,先执行async外面的同步代码,同步代码执行完,再回到async内部,把这个非promise的东西,作为 await表达式的结果。
如果它等到的是一个 promise 对象,await 也会暂停async后面的代码,先执行async外面的同步代码,等着 Promise 对象 fulfilled,然后把 resolve 的参数作为 await 表达式的运算结果。

  • 如果asycn里的代码都是同步的,那么这个函数被调用就会同步执行
  • 如果在await后面接的这个promsie都是同步的,后面的promise会同步执行
  • 如果await里面的promise没有resolve()的成功函数就不会执行await下面的线程了