🔥码云GVP开源项目 12k star Uniapp+ElementUI 功能强大 支持多语言、二开方便! 广告
# Async/await 和 Promises 区别 1. Async/await 是建立在 Promises上的,不能被使用在普通回调以及节点回调 2. Async/await 和 Promises 很像,不阻塞 3. Async/await 代码看起来像同步代码。 ## 语法 假设函数`getJSON`返回值是 Promise,并且 Promise resolves 有一些JSON 对象。我们只想调用它并且记录该`JSON`并且返回完成。 **使用Promise** ~~~ const makeRequest = () => getJSON() .then(data => { console.log(data) return "done" }) makeRequest() ~~~ **使用Async** ~~~ const makeRequest = async() => { console.log(await getJSON) return "done" } makeRequest() ~~~ ### 区别 1. 在函数前有一个关键字`async`,`await`关键字只能在使用`async`定义的函数中使用。任何一个`async`函数都会隐式返回一个`promise`,并且promise resolve 的值就是 return 返回的值 (例子中是”done”) 2. 不能在函数开头使用`await` ### 有哪些好处 1. 简洁的代码 使用async函数可以让代码简洁很多,不需要像Promise一样需要些then 1. 错误处理 Promise 中不能自定义使用 try/catch 进行错误捕获,但是在 Async/await 中可以像处理同步代码处理错误 ~~~ const makeRequest = () => { try { getJSON() .then(result => { // this parse may fail const data = JSON.parse(result) console.log(data) }) // uncomment this block to handle asynchronous errors // .catch((err) => { // console.log(err) // }) } catch (err) { console.log(err) } } ~~~ Async/await ~~~ const makeRequest = async () => { try { // this parse may fail const data = JSON.parse(await getJSON()) console.log(data) } catch (err) { console.log(err) } } ~~~ 1. 条件语句 条件语句也和错误捕获是一样的,在 Async 中也可以像平时一般使用条件语句 Promise ~~~ const makeRequest = () => { return getJSON() .then(data => { if (data.needsAnotherRequest) { return makeAnotherRequest(data) .then(moreData => { console.log(moreData) return moreData }) } else { console.log(data) return data } }) } ~~~ Async ~~~ const makeRequest = async () => { const data = await getJSON() if (data.needsAnotherRequest) { const moreData = await makeAnotherRequest(data); console.log(moreData) return moreData } else { console.log(data) return data } } ~~~ 1. 中间值 在一些场景中,也许需要 `promise1` 去触发 `promise2` 再去触发 `promise3`,这个时候代码应该是这样的 ~~~ const makeRequest = () => { return promise1() .then(value1 => { // do something return promise2(value1) .then(value2 => { // do something return promise3(value1, value2) }) }) } ~~~ 如过 `promise3` 不需要 `value1`,嵌套将会变得简单。如果你有强迫症,则将值1&2使用 `promise.all()` 分装起来。 ~~~ const makeRequest = () => { return promise1() .then(value1 => { // do something return Promise.all([value1, promise2(value1)]) }) .then(([value1, value2]) => { // do something return promise3(value1, value2) }) } ~~~ 但是使用 `Async` 就会变得很简单 ~~~ const makeRequest = async () => { const value1 = await promise1() const value2 = await promise2(value1) return promise3(value1, value2) } ~~~ 1. 错误栈 如过 Promise 连续调用,对于错误的处理是很麻烦的。你无法知道错误出在哪里。 ~~~ const makeRequest = () => { return callAPromise() .then(() => callAPromise()) .then(() => callAPromise()) .then(() => callAPromise()) .then(() => callAPromise()) .then(() => { throw new Error("oops"); }) } makeRequest() .catch(err => { console.log(err); // output // Error: oops at callAPromise.then.then.then.then.then (index.js:8:13) }) ~~~ 但是对于 Async 就不一样了 ~~~ const makeRequest = async () => { await callAPromise() await callAPromise() await callAPromise() await callAPromise() await callAPromise() throw new Error("oops"); } makeRequest() .catch(err => { console.log(err); // output // Error: oops at makeRequest (index.js:7:9) }) ~~~