どのように優雅にPromiseエラーを処理しますか?
5205 ワード
公衆番号
Promiseの出現は、広大な開発者を地域の深淵から救うことに成功しました.そしてAync/Awaitもあります.この二つは開発者が非同期コードを作成しやすくなりました.
まず要求動作をシミュレートします.
もちろんPromiseにも異常があります.
Aync/AwaitはPromiseのシンタックスキャンディーです.try-catchを使って異常を捕まえたり、Promiseのcatchを使って捕獲したりします.
に注目して、もっと前の端の小さな干物はあなたを待っていますよ.公衆番号は不定期で先端技術を共有し、毎日少しずつ進歩し、みんなと一緒に成長していきます.Promiseの出現は、広大な開発者を地域の深淵から救うことに成功しました.そしてAync/Awaitもあります.この二つは開発者が非同期コードを作成しやすくなりました.
まず要求動作をシミュレートします.
const fetchData = (url, shouldReject = false) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
shouldReject ? reject('error') : resolve('this is data');
}, 1000);
});
};
簡単にPromiseとAsync/Awaitを振り返ってみます.例えば三つの要求を出してPromiseを使ってもいいです.fetchData('url1')
.then(data => {
console.log('data1:', data);
return fetchData('url2');
})
.then(data => {
console.log('data2:', data);
return fetchData('url3');
})
.then(data => {
console.log('data3:', data);
})
.catch(error => console.log('error:', error));
よさそうですね.これもPromiseのコールバック関数の長所です.コードは優雅に見えますが、Aync/Awaitはもっと優雅にできます.(async () => {
const data1 = await fetchData('url1');
console.log('data1:', data1);
const data2 = await fetchData('url2');
console.log('data2:', data2);
const data3 = await fetchData('url3');
console.log('data3:', data3);
})();
コードが優美に見えます.さらにAync/Awaitは同期コードのように見えます.人の正常なロジックにも合致しますが、Promiseの例を見てみると、すべての異常は最後に処理されます.異常が発生した場合、この異常はどのように請求されますか?まだタイプを定義していませんか?もちろんPromiseにも異常があります.
fetchData('url1')
.catch(error => console.log('error1:', error))
.then(data => {
console.log('data1:', data);
return fetchData('url2', true);
})
.catch(error => console.log('error2:', error))
.then(data => {
console.log('data2:', data);
return fetchData('url3');
})
.catch(error => console.log('error3:', error))
.then(data => {
console.log('data3:', data);
});
// output
// data1:this is data
// error2:error
// data2:undefined
// data3:this is data
それぞれの異常を捕獲できますが、各層に異常処理が行われているため、Promiseはrejectが出現して実行を中止することはなく、書くのも面倒です.Aync/AwaitはPromiseのシンタックスキャンディーです.try-catchを使って異常を捕まえたり、Promiseのcatchを使って捕獲したりします.
(async () => {
try {
const data1 = await fetchData('url1', true);
console.log('data1:', data1);
} catch (error) {
console.log('error1:', error);
}
const data2 = await fetchData('url2', true).catch(error => console.log('error2:', error));
console.log('data2:', data2);
const data3 = await fetchData('url3').catch(error => console.log('error3:', error));
console.log('data3:', data3);
})();
// output
// error1: error
// error2:error
// data2:undefined
// data3:this is data
Promiseのcatchを使って異常を捕捉し、戻り値を処理すれば、異常処理がよく実現され、エラーが発生してから実行が停止されます.(async () => {
const data1 = await fetchData('url1', true).catch(error => console.log('error1:', error));
if (!data1) return;
console.log('data1:', data1);
const data2 = await fetchData('url2', true).catch(error => console.log('error2:', error));
if (!data2) return;
console.log('data2:', data2);
const data3 = await fetchData('url3').catch(error => console.log('error3:', error));
if (!data3) return;
console.log('data3:', data3);
})();
// output
// error1: error
もっと優雅な書き方がありますか?もちろんあります.Promiseを使った業務関数を少し処理すれば、PromiseとAync/Awaitを結合して、もっと優雅に非同期業務を処理できます.//
const fetchDataPromise = (url, shouldReject = false) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
shouldReject ? reject('error') : resolve('this is data');
}, 1000);
});
};
//
const fetchData = (url, shouldReject = false) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
shouldReject ? resolve(['error', null]) : resolve([null, 'this is data']);
}, 1000);
});
};
//
const asyncFunc = (url, shouldReject = false) => {
return fetchDataPromise(url, shouldReject)
.then(data => [null, data])
.catch(error => [error, null])
}
//
const promiseWrap = (promise) => {
return promise
.then(data => [null, data])
.catch(error => [error, null])
}
上記のような改造があったら、業務コードはこのように書くことができます.(async () => {
const [error1, data1] = await fetchData('url1', true);
if (error1) {
console.log('error1:', error1);
// do more thing
}
console.log('data1:', data1);
const [error2, data2] = await asyncFunc('url2', true);
if (error2) {
console.log('error2:', error2);
}
console.log('data2:', data2);
const [error3, data3] = await promiseWrap(fetchDataPromise('url3', true));
if (error3) {
console.log('error3:', error3);
}
})();
// output
// error1: error
// data1: null
// error2: error
// data2: null
// error3: error
// data3: null
このように書くと優雅になり、異常を扱いやすくなりますが、実はこのような処理方法はGO言語でよく見られます.