async await和promise的区别

3,495 阅读2分钟

  async await关键字是ES7的一部分,async定义在函数声明之前,使函数变成异步函数,其返回一个Promise对象;await关键字用于等待一个Promise对象,它只能在async函数中才起作用。通过使用它们,让异步代码看起来更像是老式同步代码。

  Promise是ECMAscript6原生提供的对象。Promise对象代表了未来将要发生的事件,用来传递异步操作的消息。具体详情见runoob的Promise介绍

async/await的使用

  • async函数返回一个promise对象,可以使用then方法添加回调函数
async function test(){
   return '张三'
}
// async返回的是一个promise对象,如果async函数没有返回值,async函数返回一个undefined的promise对象
test().then(res=>{
 console.log(res);//张三
})
  • 当函数执行的时候,一旦遇到await就会返回,等到异步操作完成,再接着执行函数体内后面的语句
async function test(){
   return '张三'
}
async function test1() {
    let a = await test()
    console.log(a)
}
test1() // 张三

async、await执行顺序

  • await后面的函数执行完毕时,await会产生一个微任务(promise.then是微任务),执行完await之后,直接跳出async函数,执行其他代码。
console.log('script start') 
async function async1() { 
   await async2() 
   console.log('async1 end')
} 
async function async2() { 
   console.log('async2 end') 
} 
async1() 
setTimeout(function() { 
   console.log('setTimeout') 
}, 0)
new Promise(resolve =>{
  console.log('Promise')
  resolve()
}).then(function(){
  console.log('Promise1')
})
// script start => async2 end => Promise => async1 end => promise1 => setTimeout

区别

  • 异常处理:Promise对象中提供catch方法对异常处理。async在异常处理中通过try{}catch(){}处理。
function test(a) {
    return new Promise((resolve, reject) => {
    	setTimeout(() => {
    		if (a === 1) {
    			resolve(2)
    		} else {
    			reject(3)
    		}
    	}, 1)
    })
}
// promise 异常处理
function test1(a) {
	test(a).then(e => {
		console.log(e)
	}).catch(e => {
		console.log(e)
	})
}
test1(1) // 2
test1(2) // 3
// async/await 异常处理
async function test2(a) {
	try {
		let b = await test(a)
		console.log('b', b)
	} catch(e) {
		console.log('e', e)
	}
}
test2(1) // b 2
test2(2) // e 3
  • 代码结构上async/await更接近与同步的写法。promise中引入then、catch的方法,代码更显冗余。
  • async/await结合中,大量的await的promises相继发生会使程序变慢
function test(a) {
    return new Promise((resolve, reject) => {
    	setTimeout(() => {
    		if (a === 1) {
    			resolve(2)
    		} else {
    			reject(3)
    		}
    	}, 1)
    })
}
function testPromise() {
	let i = 0, arr = []
	for (; i < 20; i++) {
		arr.push(test())
	}
	return Promise.all(arr)
}
async function testAsync() {
	let i = 0
	for (; i < 20; i++) {
		await test()
	}
	return null
}
let time = console.time()
testPromise().then(e => {
	console.timeEnd(time) // 3ms
})
setTimeout(() => {
	let time1 = console.time()
	testAsync().then(e => {
		console.timeEnd(time1) // 89ms
	})
}, 0)

总结

  async和promise都是异步方法,区别是async生成的结果是promise对象,async是promise的终结版。await只能在async中使用,await是阻塞的意思,就是暂停,你一起调用2个接口,第一个执行完,不输出结果,要等第二个接口执行完,才返回这两个的结果。

  使用async/await并不需要回调嵌套,也不需要写多个then方法,在使用上甚至类似一个同步操作。