JavaScript异步编程(五):async、宏任务、微任务

Promise 虽然主要是用来处理异步任务的,但我们深入理解 Promise 并不是纯为了来处理异步任务,因为在 ES7 里的 async 和 wait 能更简单的处理异步任务:

// 一个异步任务,在time毫秒后返回一个状态为reject的Promise对象
function ajax(time) {
    return new Promise((resolve, reject) => {
        setTimeout(() => {
            resolve(`完成了-${time}`)
        }, time)
    })
}

// 主函数
async function main() {
    const ajax1 = await ajax(600)
    console.log(ajax1)

    const ajax2 = await ajax(500)
    console.log(ajax2)

    const ajax3 = await ajax(700)
    console.log(ajax3)
}

main()

如上代码,在主函数前添加关键字 async ,主函数里面的每个异步任务前加上关键字 await ,并分别用一个变量接收返回值,异步任务处理便完成了。

上边代码按顺序执行:
在这里插入图片描述
可见,上面的3个异步任务虽然耗时各不相同,但都按照执行的先后顺序完成,并不会受耗时长短的影响。

稍加完善,正式项目中代码可能如下:

async function main() {
	try {
		const users = await ajax('/api/users.json')
		console.log(users)

		const posts = await ajax('/api/posts.json')
		console.log(posts)

		const urls = await ajax('/api/urls.json')
		console.log(urls)
	} catch (e) {
		console.log(e)
	}
}

async 和 wait 就是这么朴实无华,需要注意的是 await 不能单独使用,必须在 async 修饰的主函数里使用,不过 await 单独使用的提案已经提出,也许不久的将来 await 就可以单独使用了,那时将更加的方便。

宏任务和微任务

先看一段代码:

console.log('start')

setTimeout(() => {
    console.log('setTimeout')
}, 0)

new Promise((resolve, reject) => {
    console.log('promise')
    resolve('then')
}).then(res => {
    console.log(res)
})

console.log('end')

上面代码的执行顺序,估计很多人都理不对,正常的执行顺序如下:
在这里插入图片描述
这里涉及宏任务和微任务的概念。

new Promise() 本身和同步任务执行模式没区别,会直接执行,不会去消息队列里排队,所以在第一轮执行中,所有同步任务会按续执行,即按续打印:“start”、“promise”、“end”。

执行到 setTimeout() 的时候,会产生一个宏任务,这个宏任务会进入到消息队列中排队,等待同步任务执行完之后才会执行。

在 new Promise() 执行的时候,它后面的 then 产生一个微任务,这个微任务也会进入消息队列中排队,等待同步任务执行完之后才会执行。

同步任务执行完之后,此时消息队列中有一个宏任务和一个微任务,微任务的执行优先度比宏任务高,所以先执行微任务,再执行宏任务,所以随后先后打印:“then”、“setTimeout”。

如果你觉得理解了宏任务微任务,那么再看看下面这个代码:

new Promise((resolve, reject) => {
    console.log(1)
    resolve()
}).then(() => {
    console.log(2)
}).then(() => {
    console.log(3)
})

new Promise((resolve, reject) => {
    console.log(111)
    resolve()
}).then(() => {
    console.log(222)
}).then(() => {
    console.log(333)
})

执行试试吧,看看是否与预想的一样?

文章内容输出来源:拉勾大前端高薪训练营,以上文章中的内容根据老师讲课的语音和代码,结合自己的理解编辑完成。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值