gpt4 book ai didi

javascript - 未知数量的 promise 取决于先前 promise 的结果?

转载 作者:行者123 更新时间:2023-11-30 20:02:58 24 4
gpt4 key购买 nike

我正在尝试编写一个从 API 检索所有用户数据的函数。不幸的是,API 每次请求只返回 50 条数据。为了检索结果的下一个“页面”,需要发出另一个 GET 请求,并使用一个额外的路径指示结果页面。

(在我的例子中,API 是 Imgur,数据片段是用户的相册。)

我正在尝试使用 Promises 来做到这一点。函数 populateAlbumList 成功返回仅结果的第一页

我试图修改它以在函数 populateAlbumList2 中获得更多页的结果,但它无法正常工作。

如何让这些有条件的嵌套 promise 发挥作用? (我不想使用像 bluebird/q 这样的库,因为我想了解概念和模式本身。)

/**
* Performs an AJAX get request to the Imgur API, retrieving all the albums owned by the user. When the albums are
* populated, they are logged to the extension settings page's console.
* @returns {Promise<void>}
*/
async function populateAlbumList() {
const username = await getItemFromStorage(STORAGE_USERNAME, ERROR_STORAGE_USERNAME_NOT_FOUND);
const ALBUMS_URL = `https://api.imgur.com/3/account/${username}/albums`;

// Fetch the albums for the currently logged in user
return fetch(ALBUMS_URL, {
method: "GET",
headers: {
"Authorization": "Bearer " + CLIENT_ID,
"Content-type": "application/json; charset=UTF-8"
}
})
.then(response => response.json())
.then(json => json.data)
.then(albums => albums.forEach(album => addAlbumToPage(album)));
}

/**
* Performs an AJAX get request to the Imgur API, retrieving all the albums owned by the user. When the albums are
* populated, they are logged to the extension settings page's console.
* @returns {Promise<Array>}
*/
async function populateAlbumList2() {
const username = await getItemFromStorage(STORAGE_USERNAME, ERROR_STORAGE_USERNAME_NOT_FOUND);
let ALBUMS_URL = `https://api.imgur.com/3/account/${username}/albums`;
const allAlbums = [];
let page = 0;
const promises = [];

await getAlbumsFromImgur()
.then(() => console.log(allAlbums));

function getAlbumsFromImgur() {
if (page > 0) {
ALBUMS_URL = `https://api.imgur.com/3/account/${username}/albums` + page;
}

promises.push(
fetch(ALBUMS_URL, {
method: "GET",
headers: {
"Authorization": "Bearer " + CLIENT_ID,
"Content-type": "application/json; charset=UTF-8"
}
})
.then(response => response.json())
.then(json => json.data)
.then(albums => {
allAlbums.push(albums);

if (albums.length >= 50) {
page++;
promises.push(getAlbumsFromImgur());
}
})
);
}
}

最佳答案

由于您使用的是 async 函数,因此您无需直接处理 promises,只需使用 await 并编写您的逻辑流程。首先,让我们把它应用到只获取第一页,这样我们就可以看到它是如何简化功能的;查看 *** 评论:

async function populateAlbumList() {
const username = await getItemFromStorage(STORAGE_USERNAME, ERROR_STORAGE_USERNAME_NOT_FOUND);
const ALBUMS_URL = `https://api.imgur.com/3/account/${username}/albums`;

// Fetch the albums for the currently logged in user
// *** Use await to consume the promise
const response = await fetch(ALBUMS_URL, {
method: "GET",
headers: {
"Authorization": "Bearer " + CLIENT_ID,
"Content-type": "application/json; charset=UTF-8"
}
});
// Note: You have to check for errors
if (!response.ok) {
throw new Error("HTTP error " + response.status);
}
// Read and parse the JSON, get the `data` property from it using destructuring
// *** Use await to consume the promise
let { data: albums } = await response.json();
// Add the albums; no need for `forEach` when we have `for-of` available to us
for (const album of albums) {
addAlbumToPage(album);
}
}

现在让我们扩展该函数,让它继续请求后续页面,直到返回的结果少于 50 个:

async function populateAlbumList() {
const username = await getItemFromStorage(STORAGE_USERNAME, ERROR_STORAGE_USERNAME_NOT_FOUND);
const ALBUMS_URL = `https://api.imgur.com/3/account/${username}/albums`;

// Start on page 0
let page = 0;
let albums; // We'll need this in our while condition below
do {
// Fetch the albums for the currently logged in user,
// adding in the page if page > 0
const response = await fetch(
page === 0 ? ALBUMS_URL : ALBUMS_URL + page, // Seems odd there's no `/` or `?page=` or similar
{
method: "GET",
headers: {
"Authorization": "Bearer " + CLIENT_ID,
"Content-type": "application/json; charset=UTF-8"
}
}
);
if (!response.ok) {
throw new Error("HTTP error " + response.status);
}
// Read and parse the JSON, get the `data` from it
albums = (await response.json()).data;
// Add the albums
for (const album of albums) {
addAlbumToPage(album);
}
++page;

// Keep going until we get fewer than 50 back
} while (albums.length >= 50);
}

请注意,我还添加了一个检查以查看 fetch 是否有效,这在您的原始代码中是缺失的。不仅仅是你,大多数人都忘记了包括那张支票(以至于我 wrote it up 在我贫血的小博客上)。

关于javascript - 未知数量的 promise 取决于先前 promise 的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53177600/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com