我需要創建一個函式,它將回傳一個 Promise 并呼叫另一個將有axios.get()呼叫的函式。axios.get() 呼叫一個 API,該 API 回傳具有以下結構的資料:
{
count: 87, //total number of records
next: '[api_url]/&page=2'//indication if the API has a next page
previous: null, ////indication if the API has a previous page, if call URL above - it will return [api_url]/&page=1
results: [...] //10 objects for each call, or remaining for the last page
}
因為我知道每次呼叫只回傳 10 個結果,所以我需要檢查回傳的物件是否有next密鑰,如果有的話 - 再進行一次呼叫,依此類推,直到沒有next. 我需要連接所有結果,并最終用所有資料解決從主函式回傳的 Promise。
所以我嘗試了這樣的事情:
const fetchResource = async({type, search, page}) {
const data = {count: 0, results: []}
const request = await performFetch({type, search, page}, data).then((data) => {
console.log('data?', data)
})
console.log('req', request)
}
const performFetch = async({type, search, page}, result) => {
const params = {
page
}
if (search) {
params.search = search
}
await axios.get(`${type}/`, {
params
}).then(async({data}) => {
result.results = [...result.results, ...data.results]
result.count = data.count
if (data.next) {
page = 1
await performFetch({type, search, page}, result)
} else {
console.log('result', result)
return result
}
})
.catch((err) => {
console.error(err)
})
}
現在我看到,一旦我呼叫fetchResourche所有請求,console.log('result', result)我就會看到連接的資料:
{
count: 87,
results: [/*all 87 objects*/]
}
但是console.log('data?', data),console.log('req', request)兩者都列印出來undefined。
在我回傳的地方result,我試圖回傳Promise.resolve(result)- 同樣的結果。
而且我不確定如何在這里回傳 Promise,一旦所有 API 呼叫結束并收到所有資料,它將解決。我錯過了什么?我如何使它作業?
uj5u.com熱心網友回復:
關于您的代碼的幾點觀察:
無需將語法與
async-awaitPromise 鏈接(即方法呼叫)混合使用then()catch()在
performFetch函式內部,您需要一個顯式return宣告。目前,該函式隱式回傳一個以 的值實作的承諾undefined。這里的關鍵點是,在您獲得對 API 的 http 請求的結果之前
performFetch,該函式正在回傳。它不會在回傳之前等待回傳 HTTP 請求的結果。
以下是一個簡單的演示,說明了如何發出多個請求并聚合資料,直到 API 回傳所有資料。
顯示代碼片段
let counter = 0;
function fakeAPI() {
return new Promise(resolve => {
setTimeout(() => {
if (counter < 5) resolve({ counter: counter });
else resolve({ done: true });
}, 1000);
});
}
async function performFetch() {
const results = [];
// keep calling the `fakeAPI` function
// until it returns "{ done = true }"
while (true) {
const result = await fakeAPI();
if (result.done) break;
else results.push(result);
}
return results;
}
performFetch().then(console.log).catch(console.log);
<small>Wait for 5 seconds</small>
您的代碼可以重寫,如下所示:
const fetchResource = async ({ type, search, page }) => {
const data = { count: 0, results: [] };
const result = await performFetch({ type, search, page }, data);
console.log(result);
};
const performFetch = async ({ type, search, page }, result) => {
const params = { page };
if (search) params.search = search;
while (true) {
const { data } = await axios.get(`${type}/`, { params });
result.results = [...result.results, ...data.results];
result.count = data.count;
if (data.next) page = 1;
else return result;
}
};
理想情況下,呼叫該fetchResource函式的代碼應該在任何 HTTP 請求失敗的情況下進行錯誤處理。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/486009.html
標籤:javascript axios
下一篇:從物件回傳特定值
