異步調用無論是在web端仍是在 Node裏,都是很是常見的使用方式,簡單使用異步調用的時候,其實哪一種方式都無所謂,可是邏輯一複雜的時候,就要須要書寫更加謹慎,隨意地寫就會出現本身都搞不清當前這波操做返回什麼,還有error catch 不到的狀況,web 端和 Node 端都須要 catch 住 error 以做日誌分析。web
doFirstThing((err, data) => {
if (err) {
console.log(err);
return;
}
doSecondThing(data, function(err, data){
if (err) {
console.log(err);
return;
}
doThirdThing(data, function(err, data){
if (err) {
console.log(err);
return;
}
})
})
})
複製代碼
function takeLongTime(n) {
return new Promise(resolve => {
setTimeout(() => {
resolve(n + 200)
},)
})
}
function doThing (n) {
return takeLongTime(n);
}
const time1 = 200;
doThing(time1)
.then(time2 => doThing(time2))
.then(time3 => doThing(time3))
.catch(err => {
console.log(err)
})
複製代碼
上面的代碼每次異步調用遞進200ms,並把下次須要延遲的時間傳給下個異步函數promise
async function doThings () {
try {
const data1 = await doThing(200);
const data2 = await doThing(data1);
const data3 = await doThing(data2);
} catch (err => {
console.log(err)
})
}
複製代碼
async & await 的參數傳遞方式是否是友好多了
不少人用的時候會疑惑async 和 await 必須都上麼?跟 Promise 該如何配合使用?bash
async function getHello () {
return 'hello world';
}
console.log(getHello())
複製代碼
打印出來以下:異步
// Promise 方式
getHello.then(value => {
console.log(value) // => 輸出"hello world"
})
// await 方式
const value = await getHello();
複製代碼
上面的 await getHello()執行的時候實際會以下錯誤async
async function asyncGetHello () {
const value = await getHello();
}
複製代碼
按照設計,await 等待的是一個異步函數的返回結果,有的人會覺得這個異步函數必須是一個 async 函數,但實際上 async 或者一個 Promise實例都是能夠的,甚至不是個異步函數,一個直接量也都能正確返回。函數
async function asyncDemo () {
// await 一個 async 函數
await getHello();
// await 一個 Promise 示例
await new Promise(function (resolve, reject) {
resolve('result');
})
// await 一個直接涼
await 1+1;
}
複製代碼
try{
new Promise(function (reslove, reject) {
throw new Error('有 error 拉');
})
.then(() => {
},err => {
console.log('failCallback',err)
})
.catch(err => {
console.log('promise catch error', err)
})
} catch (err) {
console.log('try catch error', err)
}
複製代碼
代碼執行後實際以下ui
try {
[1,2,3].map(async (data) => {
await doThing();
})
} catch (err) {
console.log('try catch error', err)
}
複製代碼
上面的代碼永遠不會 catch 到 error
Node 端能夠在下面的事件中 catch 住spa
process.on('unhandledRejection', (reason, p) => {
logger.error('Unhandled Rejection at:', p, 'reason:', reason);
});
複製代碼
但若是咱們不想要在unhandledRejection的回調裏處理,仍是想在 try catch 裏統一處理呢,能夠用以下方式設計
try {
async function map&async() {
await Promise.all([1,2,3].map(async (data) => {
await doThing();
}));
}
} catch (err) {
console.log('try catch error', err)
}
複製代碼