async/await/Promise以及js中的微任务和宏任务之间的关系

宏任务与微任务

同步和异步任务分别进入不同的执行"场所",同步的任务进入主线程,异步的进入Event Table并注册函数。当异步函数完成时,Event Table会将这个函数移入Event Queue。主线程内的任务执行完毕为空,会去Event Queue读取对应的函数,进入主线程执行。上述过程会不断重复,也就是常说的Event Loop(事件循环)。

除此之外,在js中还存在宏任务和微任务。
js中的宏任务一般是:包括整体代码script,setTimeout,setInterval。
微任务是:Promise,process.nextTick。

一段代码执行时,会先执行宏任务中的同步代码:

如果执行中遇到 setTimeout 之类宏任务,那么就把这个 setTimeout 内部的函数推入「宏任务的队列」中,下一轮宏任务执行时调用。

如果执行中遇到 promise.then() 之类的微任务,就会推入到「当前宏任务的微任务队列」中,在本轮宏任务的同步代码执行都完成后,依次执行所有的微任务1、2、3。

asyinc与await与Promise

async-await是promise和generator的语法糖。只是为了让我们书写代码时更加流畅,当然也增强了代码的可读性。简单来说:async-await 是建立在 promise机制之上的,并不能取代其地位。

async

若 async 定义的函数有返回值,return 123;相当于Promise.resolve(123)

async function demo01() {
    return 123;
}

demo01().then(val => {
    console.log(val);// 123
});

没有声明式的 return则相当于执行了Promise.resolve();

async function demo01() {
    console.log("withOut return")
}

demo01().then(val => {
    console.log(val);// undefined
});

await

await 可以理解为是 async wait 的简写。await 必须出现在 async 函数内部,不能单独使用。

function notAsyncFunc() {
    await Math.random();
}
notAsyncFunc();//Uncaught SyntaxError: Unexpected identifier

await 后面可以跟任何的JS 表达式。虽然说 await 可以等很多类型的东西,但是它最主要的意图是用来等待 Promise 对象的状态被 resolved。

如果 await 的是 promise对象,await 会暂停 async 函数内后面的代码,先执行 async 函数外的同步代码(注意,promise 内的同步代码会先执行),等着 Promise 对象 fulfilled,然后把 resolve 的参数作为 await 表达式的运算结果返回后,再继续执行 async 函数内后面的代码

function sleep(second) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(' enough sleep~');
        }, second);
    })
}
async function awaitDemo() {
    let result = await sleep(2000);
    console.log(result);// 两秒之后会被打印出来
}
console.log("主线程1")
awaitDemo();
console.log("主线程2")
//主线程1
//主线程2
//enough sleep~

如果 await 的不是一个 promise ,而是一个表达式。await 会暂停 async 函数内后面的代码执行,先执行 async 函数外的同步代码(注意,此时会先执行完 await 后面的表达式后再执行 async 函数外的同步代码)

function sleep(second) {
 	return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(' enough sleep~');
        }, second);
    })
}
function normalFunc() {
    console.log('normalFunc');
}
async function awaitDemo() {
    await normalFunc();
    console.log('something, ~~');
    let result = await sleep(2000);
    console.log(result);// 两秒之后会被打印出来
}
console.log("主线程1")
awaitDemo();
console.log("主线程2")
//主线程1
//normalFunc
//主线程2
//something, ~~
//enough sleep~

下面来一个混合一起使用的示例

async function async1() {
  console.log('async1 start')// 2  主线程async1()调用
  await async2()
  console.log('async1 end')  // 6 主线程内同步代码执行完毕后接着执行await函数内后面的代码(至此主线程内同步代码都执行完毕)
}

async function async2() {
  console.log('async2')// 3 主线程async1() => async2()  await 会先执行完async2()内的代码
}

console.log('script start')// 1  主线程同步代码
setTimeout(function() { 
  console.log('setTimeout') // 8 setTimeout放入宏队列中下次轮询执行
}, 0)

async1(); 
  
new Promise( function( resolve ) {
  console.log('promise1') // 4 promise内的同步代码会在主线程内先执行
  resolve();
} ).then( function() {
  console.log('promise2') // 7 promise回调会放入微队列中,主线程代码执行完毕后执行
} )

console.log('script end') // 5 主线程同步代码
//script start
//async1 start
//async2
//promise1
//script end
//async1 end
//promise2
//setTimeout
  • 7
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值