鸿蒙征文|HarmonyOS NEXT 优雅的处理 Promise await异常
优雅的处理HarmonyOS NEXT 中的 async/await异常捕获,优雅的处理鸿蒙纯血版 中的 async/await异常捕获,优雅的处理鸿蒙 中的 async/await异常捕获
·
1. 背景
如果await
后面的异步操作出错,则会抛出异常,不继续执行后面的逻辑
例如:
async function test() {
console.log("test 开始")
let result=await new Promise<string>((resolve, reject) => {
setTimeout(() => {
reject("hello world");
}, 1000);
});
console.log("test 结束")
}
test();
//只会输出 test 开始,不会输出 test 结束
防止出错的方法,也是将其放在try...catch
代码块之中。
async function test() {
console.log("test 开始")
try {
let result=await new Promise<string>((resolve, reject) => {
setTimeout(() => {
reject("hello world");
}, 1000);
});
console.log(result)
} catch (e) {
console.error("异常:"+e)
}
console.log("test 结束")
}
//输出
test 开始
异常:hello world
test 结束
2. 优雅的异常处理
从上面的例子我们发现,如果每个请求的地方都添加 try-catch,就会显得代码很臃肿,解决这样的臃肿代码,我们可以用await-to-js函数
await-to-js 是 前端 中的一个三方库,它的源码很简单,就 23 行代码,我们一起来看看。
/**
* @param { Promise } promise
* @param { Object= } errorExt - Additional Information you can pass to the err object
* @return { Promise }
*/
export function to<T, U = Error>(
promise: Promise<T>,
errorExt?: object
): Promise<[U, undefined] | [null, T]> {
return promise
.then<[null, T]>((data: T) => [null, data])
.catch<[U, undefined]>((err: U) => {
if (errorExt) {
const parsedError = Object.assign({}, err, errorExt)
return [parsedError, undefined]
}
return [err, undefined]
})
}
export default to
大致流程如下: 函数to
接受参数Promise
和errorExt
,如果这个 Promise 成功时返回[null, data]
,如果异常时会判断是否带有errorExt
参数(代表传递给 err 对象的附加信息),如果有时会与 catch 捕获的 err 合并返回,如果没有时返回[err, undefined]
。
3. 在非ArkTS中的用法
- 通过
to
函数改造后,如果返回第一个参数不为空时,说明该请求报错,就可以提前 return 出去,如果不存在第一个参数时,则异步请求成功。
import to from 'await-to-js'
function getList(){
return new Promise<string>((resolve, reject) => {
//我是一个网络请求,可能成功,可能失败
})
}
// 获取列表list 如果err有值,则是异常,否则是成功, 可以继续下方的逻辑
const [err, data] = await to(getList(params))
if (err) return
4. 在ArkTS中的用法
上述代码,如果用在ArkTS中,我们会发现无法使用,const [err, data] 这种写法目前在ArkTS不支持解构变量声明,为了解决,我们可以使用一个包装类 PromiseResult 来实现
//Global.ts
/**
* @param { Promise } promise
* @param { Object= } errorExt - Additional Information you can pass to the err object
* @return { Promise }
*/
export function safePromise<T, U = Error>(
promise: Promise<T>,
errorExt?: object
): Promise<PromiseResult<T, U>> {
return promise
.then<PromiseResult<T, U>>((data: T) => new PromiseResult(data, null))
.catch<PromiseResult<T, U>>((err: U) => {
if (errorExt) {
const parsedError = Object.assign({}, err, errorExt);
return new PromiseResult(undefined, parsedError)
}
return new PromiseResult(undefined, err)
});
}
class PromiseResult<T, U = Error> {
result: T
error: U
constructor(result: T, error: U) {
this.result = result
this.error = error
}
}
export default safePromise;
使用例子
import safePromise from 'Global.ts';
async function test() {
console.log("test 开始")
const data = await safePromise(new Promise<string>((resolve, reject) => {
setTimeout(() => {
reject("hello world");
}, 1000);
}));
if (data.error) {
console.error("异常了")
}else{
console.log("没有异常")
}
console.log("test 结束")
}
test();
//输出
test 开始
异常了:hello world
test 结束
更多推荐
已为社区贡献2条内容
所有评论(0)