0%

Promise,async/await 异步调用

Javascript单线程,同步执行的语言。早期只是简单处理静态数据,这没问题。但是后来越来越多需要js去访问网络,所以需要一种异步机制。于是有了很多非阻塞,依赖Event Loop的web api可以实现异步。但这种web api需要写很多callback函数。

但是callback层级一旦多了以后,代码变得不可读,不可维护,于是ES6就给出Promise的异步方案

Promise
1
2
3
4
5
6
7
8
9
10
11

function executor(resolveFunc, rejectFunc) {
setTimeout(() => resolveFunc(1), 1000); // (*)
}


function handleResult(resp) { // (**)
console.log(resp)
}

new Promise(executor).then(handleResult)

Promise可以看成是一个类,他生成的对象可以在未来把异步操作的结果返回回来。他实现了callback相同的功能,但包含了新特性,而且有更具可读性的语法。很多Web API实际上就是返回一个Promise对象。

Promise通过new语法生成一个包含状态和结果的对象。创建对象时,需要传入一个函数,就是那个耗时的函数,这个函数需要有两个参数,分别表示成功和失败后的操作,这两个函数resolve,reject是Promise提供,只需要在executor中正确调用即可。

Promise对象通过.then()来绑定一个结果处理函数,当Promise对象已经resolve的时候,在then()登记的函数就会被执行,内部是通过MicroQueue实现的。then()函数把resolve收到的参数,传给handleRequest来处理。

很多WebAPI返回的就是Promise对象,所以不需要自己去new,只需要好好处理then()就可以了,比如fetch API。

1
2
3
4
5
6
7
8
9
10
11
// Fetch a user from the GitHub API
fetch('https://api.github.com/users')
.then((response) => {
return response.json()
})
.then((data) => {
console.log(data)
})
.catch((error) => {
console.error(error)
})
Async/Await

Promise的好处就是去掉了callback嵌套,但是还是把代码分成了两块。ES7又提出async和await关键字。

通过async可以把普通函数变成异步函数,就是就是把这个函数当做executor放到一个Promise对象里面,然后返回一个Promise对象。

1
2
3
async function myFunction() {
// 这是一个异步函数
}

在异步函数中,你可以在调用一个返回 Promise 的函数之前使用 await 关键字。这使得代码在该点上等待,直到 Promise 被完成,这时 Promise 的响应被当作返回值,或者被拒绝的响应被作为错误抛出。

  1. async可以把普通函数变成异步函数,返回值是一个promise
  2. 加了async后,想获得函数的返回值,必须通过.then()语句
  3. 在async函数中,可以使用await。await只能在async函数中使用
  4. 通过使用await,相当于代码一直同步等到异步API返回值以后,代码再继续运行。或者说通过await,避免了.then()的链式调用