如何在寫await async的時候不用try catch
阿新 • • 發佈:2019-05-10
直接 ted cte span 簡單 捕獲 odi with signed
在js的日常使用中,異步操作是經常會用到的,promise 和 await/async可以避免會掉地獄的痛苦。
我們可以用promise的鏈式回調處理異步結果,但是當有多個異步需要處理的時候也會避免不了要用一串的then函數來處理
function asyncTask(cb) {
asyncFuncA.then(AsyncFuncB)
.then(AsyncFuncC)
.then(AsyncFuncD)
.then(data => cb(null, data)
.catch(err => cb(err));
}
這個時候可以用await/async來處理多個異步調用的情況
async function asyncTask(cb) {
const user = await UserModel.findById(1);
if(!user) return cb(‘No user found‘);
const savedTask = await TaskModel({userId: user.id, name: ‘Demo Task‘});
if(user.notificationsEnabled) {
await NotificationService.sendNotification(user.id, ‘Task Created‘);
}
if(savedTask.assignedUser.id !== user.id) {
await NotificationService.sendNotification(savedTask.assignedUser.id, ‘Task was created for you‘);
}
cb(null, savedTask);
}
這樣看的話異步可以像同步那樣處理很簡潔易讀,但是錯誤的捕獲卻做不到,這裏需要用到try/catch來做錯誤的處理
async function asyncTask(cb) {
try {
const user = await UserModel.findById(1);
if(!user) return cb(‘No user found‘);
} catch(e) {
return cb(‘Unexpected error occurred‘);
}
try {
const savedTask = await TaskModel({userId: user.id, name: ‘Demo Task‘});
} catch(e) {
return cb(‘Error occurred while saving task‘);
}
if(user.notificationsEnabled) {
try {
await NotificationService.sendNotification(user.id, ‘Task Created‘);
} catch(e) {
return cb(‘Error while sending notification‘);
}
}
if(savedTask.assignedUser.id !== user.id) {
try {
await NotificationService.sendNotification(savedTask.assignedUser.id, ‘Task was created for you‘);
} catch(e) {
return cb(‘Error while sending notification‘);
}
}
cb(null, savedTask);
}
所以就成了上面這樣,這樣看來代碼量和簡潔程度都不是很友好,為了能夠使異步可以像寫同步一樣易於理解,以及代碼盡量簡單減少嵌套,可以考慮封裝一種函數擁有promise的便捷錯誤處理和await/async的簡潔的寫法,因為await 後面本來就是一個promise所以我們直接可以先處理promise 用catch來捕獲error,在返回一個promise 交給await處理。
export default function to(promise) {
return promise.then(data => {
return [null, data];
})
.catch(err => [err]);
}
下面我們來測試一下這個方法的可行性
function taskPromise(status) {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (status === "fail") {
return reject("error")
} else {
return resolve("success")
}
}, 1000)
})
}
async function asyncTasks() {
let err, result
[err, result] = await to(taskPromise(""))
if (err) {
console.log("it‘s error")
} else {
console.log("it‘s" + result)
}
[err, result] = await to(taskPromise("fail"))
if (err) {
console.log("it‘s error")
} else {
console.log("it‘s" + result)
}
}
asyncTasks() //it‘ssuccess it‘s error
參考:https://blog.grossman.io/how-to-write-async-await-without-try-catch-blocks-in-javascript/
如何在寫await async的時候不用try catch