[英]How the promise.then mechanisem works?
觀看視頻並閱讀 [Promise.then][1] 后,我仍然不明白它是如何工作的。 所以我寫了一個例子,並打印到控制台,但仍然使用 output 我無法理解它是如何工作的。 我希望我的問題足夠清楚,如果沒有,請告訴我,我會根據您的回答嘗試詳細說明。 這是我的代碼:
const getCountryData = function (country) {
fetch(`https://restcountries.eu/rest/v2/name/${country}`)
.then(response => {
console.log('111111111111111');
if (!response.ok)
throw new Error(`Country not found (${response.status})`);
return response.json();
})
.then(data => {
console.log('22222222222');
const neighbour = data[0].borders[0];
if (!neighbour) return;
return fetch(`https://restcountries.eu/rest/v2/alpha/${neighbour}`);
})
.then(response => {
console.log('333333333')
if (!response.ok)
throw new Error(`Country not found (${response.status})`);
return response.json();
})
.then(data => console.log('44444444444'))
.catch(err => {
console.error(`${err} 💥💥💥`);
})
.finally(() => {
console.log('finalyyyy')
});
console.log("after all async calls");
};
我無法理解以下內容:
then
函數不接收回調,它們接收上一個異步操作的結果。 所以fetch
的結果被傳遞給第一個then
, response.json()
的結果被傳遞給第二個then
等等......
萬一出現錯誤,鏈條會斷裂,它會直接到達第一個catch
function。
在幕后還有更多,考慮到then
函數中的 fetch 和其他操作可以是異步的,所以在運行時發生的是 fetch function 的結果被推送到事件隊列中,當事件循環采取你的下一個然后從隊列中提取 function 並傳遞給 function。
本文解釋了它是如何在內部工作的: https://www.digitalocean.com/community/tutorials/understanding-the-event-loop-callbacks-promises-and-async-await-in-javascript
我將嘗試使用async/await
運算符以不同的方式解釋這一點。
你的getCountryData
function 的等價物如下
const getCountryData = async (country) => {
console.log("after all async calls"); // explanation for the this line below
try {
let response1 = await fetch(`https://restcountries.eu/rest/v2/name/${country}`);
// first then
console.log('111111111111111');
if (!response1.ok)
throw new Error(`Country not found (${response1.status})`);
let data1 = await response1.json();
// second then
console.log('22222222222');
const neighbour = data1[0].borders[0];
let response2;
if (neighbour)
response2 = await fetch(`https://restcountries.eu/rest/v2/alpha/${neighbour}`);
// third then
console.log('333333333');
if (!response2.ok)
throw new Error(`Country not found (${response2.status})`);
let data2 = await response2.json();
// fourth then
console.log('44444444444');
} catch (err) {
console.error(`${err} 💥💥💥`);
} finally {
console.log('finalyyyy');
}
}
首先,你會看到你最后一行 function 中的console.log
變成了我的 function 的第一行。 這是因為該行在異步 function fetch
完成之前執行。
如您所見, fetch
的最后一個返回變量在第一個then
中可用,而then
then
可用。
那么對於你的第一個問題, then
誰調用回調 function 呢? 顯然,您可以從 function 的async/await
等效項中看到,它是按順序執行的。 前一個then
的返回結果將是下一個then
的參數。 因此,在第二個then
中,當您return;
,它不會停止執行第三個then
,而是第三個then
將接收undefined
作為response
參數。
如對問題 1 的回答所述,只要沒有未處理的錯誤或拒絕 promise,則then
函數會自動按順序執行。 但是,對於第二個/第三個/第四個then
回調 function 從第一個then
訪問參數,不可能直接訪問,除非您將它與后續then
的每個 return 一起傳遞。 這可以通過使用 then async/await
運算符而不是then
輕松實現。
當拋出錯誤時,代碼究竟是如何知道跳轉到 catch function 的? 在異步 function 中,拋出錯誤幾乎等同於拒絕 promise。 這樣想,每個then
回調都包裝在一個try/catch
塊中,該塊將調用catch
中的 function 。
編輯:如果您執行fetch().then().then().catch()
,所有錯誤或被拒絕的承諾都將在 catch function 中處理。 但是如果你執行fetch().catch().then().then()
,只有錯誤或被拒絕的fetch
將在 catch function 中處理。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.