async 函数的返回值始终是一个 Promise 对象。
async function example1() {
return 'Hello, world!';
}
example1().then(result => {
console.log(result); // 输出: Hello, world!
});
在这个示例中,example1 函数返回字符串 ‘Hello, world!’,但是由于它是一个 async 函数,这个返回值会被封装在一个解决的 Promise 中。
- 没有返回值:async 函数返回一个resolved的 Promise,其值为 undefined。
- 有返回值:async 函数返回一个resolved的 Promise,其值为返回的值
- 抛出错误:async 函数返回一个rejected的 Promise,其错误为抛出的错误。
// 批量删除
async deleteBatch () {
await this.deleteContent(this.multipleSelection);
console.log("1");
},
// 单个删除
async deleteContent (id) {
MessageBox.confirm('您确定删除', '删除', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
const response = await deleteUser({ ids: id.toString() });
Message({
message: '删除成功',
type: 'success',
duration: 3 * 1000
});
this.init();
})
}
在上面的代码中,批量删除时,await失效,直接打印“1”,由于在执行 deleteContent函数时,MessageBox.confirm 是一个异步函数,并且没有等待其执行完毕,就直接结束了deleteContent函数,函数会返回一个值为undefined的Promise。
控制台报错Uncaught (in promise) cancel,是因为点击cancel时,MessageBox.confirm 会返回一个 Promise,当用户确认或取消时,该 Promise 会解决或拒绝。如果用户取消,Promise 会被拒绝,需要catch接收。
正确代码:
async deleteBatch () {
await this.deleteContent(this.multipleSelection)
console.log("1");
},
// 单个删除
async deleteContent (id) {
await MessageBox.confirm('您确定删除', '删除', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(async () => {
const response = await deleteUser({ ids: id.toString() });
Message({
message: '删除成功',
type: 'success',
duration: 3 * 1000
});
this.init();
}).catch(error => {
// 用户取消操作,不做任何处理
})
MessageBox.confirm 是一个异步函数,在嵌套的函数中,也需要await等待执行完毕,再接着执行。
拓展
1.在方法中需要调用,函数返回的结果后,在继续下一步,await发现不生效,原因如下:
async和await ,这个await只有在他等待的函数返回的是Promise的时候才会生效,所以异步操作必须包含Promise里面。
解决方法:不生效时,考虑await的方法是否返回的是Promise,若不是,用Promise包装即可。
2.其他不生效的原因需要具体情况具体分析,如:
map/forEach中await一个返回的Promise的函数依然不生效,原因map/forEach内部使用了while结合callback方式来执行函数,await不会等待callback的执行。
解决方法:改用for循环,或者在map/forEach外,用promise.all()包装。
3.无论响应拦截器返回什么类型的值,最终在使用 Axios 时,所有的处理结果都会以 Promise 的形式呈现。
Axios 是一个基于 Promise 的 HTTP 库,Axios返回的就是一个promise对象。
axios拦截器执行顺序
async和await
在 JavaScript 中,任务队列机制分为三类:同步任务、微任务(microtasks)和宏任务(macrotasks)。理解这些任务类型及其执行顺序是掌握 JavaScript 异步编程和事件循环的关键。
-
同步任务
同步任务是立即执行的任务,在执行栈中按照顺序依次执行。所有同步任务都会在任何异步任务之前执行。 -
微任务
微任务是一种异步任务,但它的执行优先级高于宏任务。微任务会在当前事件循环结束后,立即执行。常见的微任务包括:
a. Promise.then 和 Promise.catch 回调
b. MutationObserver 回调
c. queueMicrotask -
宏任务
宏任务也是一种异步任务,但它的执行优先级低于微任务。宏任务通常包括:
a. setTimeout
b. setInterval
c. setImmediate(仅在 Node.js 环境中)
d. I/O 任务
e. UI 渲染任务 -
事件循环
事件循环负责协调同步任务、微任务和宏任务的执行顺序:
a. 同步任务:所有同步任务都在主线程上按顺序执行,直到执行栈为空。
b. 微任务队列:执行栈清空后,立即执行微任务队列中的所有任务,直到微任务队列为空。
c. 宏任务队列:当微任务队列为空时,从宏任务队列中取出一个任务并执行,然后进入下一轮事件循环。

init开始
定时器开始
init结束
定时器ing
定时器结束
上面的代码执行结果如上,init函数如果需要showdialog执行结束再“init结束”,则仍旧需要加async和await,因为showdialog中的awiat只能限制该作用域的,对init函数中的init结束来说,没有限制,仍旧是同步代码。
1316

被折叠的 条评论
为什么被折叠?



