我需要從多個 API 獲取資料,所有這些 API 的回傳資料都很慢。
第一個 API 回傳基礎資料。呼叫其他 API 不需要此資訊,但需要處理它們的結果。因此,雖然我可以并行發送所有請求,但我需要先處理第一個請求的結果。
例如,請求 nr 1 在 30 秒后回傳,nr 2 在 15 秒后回傳,nr 3 在 60 秒后回傳。這意味著在 30 秒后我可以處理 nr 1 和 2 的結果,在 60 秒后我可以處理 nr 3。我希望能夠盡快處理基礎資訊以向用戶提供反饋。
我將如何在 JavaScript 中執行此操作?
我可以使用 Promise.all 等待處理,直到所有提取完成,但這可能需要很長時間才能顯示任何結果。(在我的示例中,60 秒。)我也可以自己啟動第一次提取,并在處理第一個回復后使用 Promise.all 來處理其余部分,但這意味著其他所有內容都會被第一個請求延遲(即 30 秒) )。
我感覺解決方案是使用 async/await,但我不知道怎么做。
uj5u.com熱心網友回復:
您似乎正在尋找多個Promise.all呼叫,每個呼叫都有基本請求和其他請求之一。
const base = baseRequest().then(preprocess);
Promise.all([
Promise.all([base, firstRequest()]).then(([baseData, firstData]) => processFirst(baseData, firstData)),
Promise.all([base, secondRequest()]).then(([baseData, secondData]) => processSecond(baseData, secondData)),
Promise.all([base, thirdRequest()]).then(([baseData, thirdData]) => processThird(baseData, thirdData)),
…
]).catch(err => {
// handle (first) error from any of the above
})
(您還可以根據需要添加單獨的錯誤處理)
這將同時觸發所有請求,并在它們各自需要的資料可用時立即呼叫processFirst// 。一旦所有處理完成,外部就會完成,你也可以將一些東西鏈接到它上面。processSecondprocessThirdPromise.all
uj5u.com熱心網友回復:
Promise.all您可以通過幾個呼叫(正如您所懷疑的那樣)結合一個顯式的 promise 回呼來相當簡單地做到這一點。這部分取決于您何時要處理“其他”結果。
如果您想盡快處理“基礎”但“其他”結果只有在它們全部到達之后
...它看起來像這樣:
async function doTheWork() {
const [processedBaseResult, otherResults] = await Promise.all([
baseQuery().then(rawBaseResult => processBase(rawBaseResult)),
Promise.all([
otherQuery(1),
otherQuery(2),
otherQuery(3),
])
]);
// ...process `otherResults` here, using `processedBaseResult`...
return otherResults.map(otherRaw => processOther(processedBaseResult, otherRaw));
}
這將并行啟動所有作業,在基本結果可用時立即處理(通過.then回呼),并等待一切完成。一切完成后,您可以使用已處理的基本結果來處理其他結果。
顯示代碼片段
const rnd = () => Math.floor(Math.random() * 300);
const baseQuery = () =>
new Promise(resolve => setTimeout(resolve, rnd(), "base result"));
const otherQuery = (value) =>
new Promise(resolve => setTimeout(resolve, rnd(), `other result #${value}`));
const processBase = (raw) => raw " processed";
const processOther = (baseProcessed, otherRaw) => baseProcessed ": " otherRaw
async function doTheWork() {
const [processedBaseResult, otherResults] = await Promise.all([
baseQuery().then(rawBaseResult => processBase(rawBaseResult)),
Promise.all([
otherQuery(1),
otherQuery(2),
otherQuery(3),
])
]);
// ...process `otherResults` here, using `processedBaseResult`...
return otherResults.map(otherRaw => processOther(processedBaseResult, otherRaw));
}
doTheWork().then(console.log).catch(console.error);
如果您想盡快處理“基礎”并盡快處理“其他”結果
...看起來像這樣:
async function processOther(basePromise, otherPromise) {
const [baseResult, otherRaw] = await Promise.all([basePromise, otherPromise]);
return baseResult ": " otherRaw;
}
async function doTheWork() {
const basePromise = baseQuery().then(rawBaseResult => processBase(rawBaseResult));
const otherResults = await Promise.all([
processOther(basePromise, otherQuery(1)),
processOther(basePromise, otherQuery(2)),
processOther(basePromise, otherQuery(3)),
]);
return otherResults;
}
這使您可以盡快開始處理每個“其他”結果,等待整個程序完成。請注意,盡管我們await basePromise不止一次,但這絕對沒問題;所有這些都將獲得相同的履行價值。
顯示代碼片段
const rnd = () => Math.floor(Math.random() * 300);
const baseQuery = () =>
new Promise(resolve => setTimeout(resolve, rnd(), "base result"));
const otherQuery = (value) =>
new Promise(resolve => setTimeout(resolve, rnd(), `other result #${value}`));
const processBase = (raw) => raw " processed";
async function processOther(basePromise, otherPromise) {
const [baseResult, otherRaw] = await Promise.all([basePromise, otherPromise]);
return baseResult ": " otherRaw;
}
async function doTheWork() {
const basePromise = baseQuery().then(rawBaseResult => processBase(rawBaseResult));
const otherResults = await Promise.all([
processOther(basePromise, otherQuery(1)),
processOther(basePromise, otherQuery(2)),
processOther(basePromise, otherQuery(3)),
]);
return otherResults;
}
doTheWork().then(console.log).catch(console.error);
uj5u.com熱心網友回復:
你可以做這樣的事情
const timeOutPromise = (data, time) => new Promise(resolve => setTimeout(() => resolve(data), time))
const promise1 = timeOutPromise("first api data", 3000);
const promise2 = timeOutPromise("second api data", 1500);
const promise3 = timeOutPromise("third api data", 5000);
promise1.then(d => console.log(d))
promise2.then(d => {
console.log(d)
promise1.then(d => {
console.log("promise 1 and 2 resolved")
})
})
promise3.then(d => {
console.log(d)
promise1.then(d => {
console.log("promise 1 and 3 resolved")
})
})
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/461454.html
標籤:javascript 承诺 拿来
上一篇:在函式中呼叫React鉤子
