赞
踩
对于js而言,我们平时使用promise情况是十分常见的 ,然而有些地方并没有很好地使用,这篇文章介绍常见的promise不规范示范和正确使用方式。
通常开发过程中,我们页面都有loading,使用Promise前开启loading,结束的时候关闭loading。但有些小伙伴会在then和catch里面结束,这样不够优雅,其实最好是在finally里面结束。
正确示范:
let isLoading = true
const result = await promiseSuccess()
.finally(() => {
isLoading = false
})
错误捕获可以使用.catch 和try catch,二者是由区别的,最大区别是try catch只要捕获到一个错误就会中断后续代码,但.catch不会,需要结合resolve结果来中断代码。
现在我们拥有2个方法
该方法100%返回resolve(true)
该方法100%返回reject(new Error("出错了"))
/** promise成功 */
function promiseSuccess() {
return new Promise((resolve) => {
resolve(true)
})
}
/** promise失败 */
function promiseFail(errorStr = '出错了') {
return new Promise((resolve, reject) => {
reject(new Error(errorStr))
})
}
console.log(1)
await promiseSuccess().catch((error) => {
console.log(error)
})
console.log(2)
await promiseFail().catch((error) => {
console.log(error)
})
console.log(3)
1
2
Error: 出错了
3
通常我们是发生错误的时候需要中断代码执行
,那么需要结合resolve结果来判断是否要中断代码,正确写法是
console.log(1)
const result1 = await promiseSuccess().catch((error) => {
console.log(error)
})
if (!result1) return
console.log(2)
const result2 = await promiseFail().catch((error) => {
console.log(error)
})
if (!result2) return
console.log(3)
1
2
Error: 出错了
上述代码好像有点啰嗦,所以我们可以用try catch,正确代码:
try {
console.log(1)
const result1 = await promiseSuccess()
console.log(2)
const result2 = await promiseFail()
console.log(3)
} catch (error) {
console.log(error)
}
1
2
Error: 出错了
首先,Promise方法内使用return是不建议的,如果有用eslint,那么会提示 no-return-await
,我们看看如果用return会由什么结果
resolve前
执行return/** promise成功 */
function promiseSuccess() {
return new Promise((resolve) => {
return 'return'
resolve(true)
})
}
console.log(1)
const result = await promiseSuccess().catch((error) => {
console.log(error)
})
console.log('result', result)
if (!result) return
console.log(2)
1
resolve后
执行return/** promise成功 */
function promiseSuccess() {
return new Promise((resolve) => {
resolve(true)
return 'return'
})
}
1
result true
2
await只会获取resolve结果,里面的return值并没有影响
。await 不仅仅用于等 Promise 对象,它可以等任意表达式的结果,所以,await 后面实际是可以接普通函数调用或者直接量的。等待这个操作完成才能进行await语句下面的程序。
await后面跟的不是promise对象,会将其他值包装成一个promise对象
(async function(){
const res = await 400 //Promise.resolve(400)
console.log(res) //400
})()
await后面跟普通函数,接收return值(可以是异步函数)
(async function(){
const res = await getData(false) // 这里会等待getData函数执行完毕,接收return值
})()
async function getData(param){
if(param) return 1
const res = await otherFun()
return res
}
不建议将 async 函数传递给 new Promise 的构造函数;
如果下面代码,如果有用eslint会提示 no-async-promise-executor,原因是async本来是异步的,就无必要嵌套在Promise里面了。
// 错误示范: function promiseTest() { return new Promise(async (resolve) => { const result = await promiseSuccess() resolve(result) }) } // 正确示范1: async function promiseTest() { const result = await promiseSuccess() return result } // 正确示范2,如果硬要使用Promise,那么可以这样: async function promiseTest() { const result = await promiseSuccess() return new Promise((resolve) => { resolve(result) }) }
const result1 = await promiseTest().catch((error) => {
console.log(error)
})
console.log('result1', result1)
不建议在循环里使用 await,有这种写法通常意味着程序没有充分利用 JavaScript 的事件驱动。
通常情况下可以使用Promise.all 代替。
// 错误示范: async function foo(things) { const results = []; for (const thing of things) { results.push(await bar(thing)); } return baz(results); } // 正确示范: async function foo(things) { const results = []; for (const thing of things) { results.push(bar(thing)); } return baz(await Promise.all(results)); }
但是,如果每一次循环都需要改变数据,并且这个数据会带入到下次循环里,这种情况是可以使用循环里嵌套await的!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。