[英]Node.js - Promise not resolving within loop
大家好,
我正在使用 Axios for Node.js 从 PipeDrive 的 API 中提取一些数据。 PipeDrive 开发其 API 分页的方式有点不同。 这是他们的分页指示器的外观:
"additional_data": {
"pagination": {
"start": 0,
"limit": 100,
"more_items_in_collection": true,
"next_start": 100
}
}
我需要遍历所有页面来提取数据,我的代码已经成功地做到了这一点,但由于某种原因我无法得到我的承诺。
我在代码中的逻辑如下:
if(more_items_in_collection){Add current page's data then re-run the same function with the next_start as a parameter}
else{Add current page's data then RESOLVE the promise to complete the function}
但是这个解决方案永远不会发生,即使我的代码有效(奇怪)。
大师,你能不能看看我的代码,让我知道为什么你认为它不会解决( function().then((result) => {OUTPUT})
永远不会返回发生)?
一如既往的感谢!
const queryPipeDrive = (start) =>{
// Query is a full then-able Async function
return new Promise((resolve, reject) => {
// API CALL
axios({
method: 'GET',
url: pipeDriveURI,
params: {
api_token: apiKey,
start: start
}
})
// THEN DO THIS
.then((response) => {
// IF there are more items in collection on additional pages, iterate through the pages
if(response.data.additional_data.pagination.more_items_in_collection){
// Add all deals on page to the container
for (const deal of response.data.data) {
db.get('deals').push(deal) // Push deal data to the StormDB File
}
console.log(chalk.cyan(`${response.data.additional_data.pagination.next_start}`))
// Function loop created. We will loop UNTIL the 'more_items_in_collection' prop is false, then we'll resolve the promise.
queryPipeDrive(response.data.additional_data.pagination.next_start)
}else{
// Add all deals on this page to the reponse container
for (const deal of response.data.data) {
db.get('deals').push(deal)
}
db.save() // Save changes to temp DB
resolve(response.data.data) // Resolve Promise with the data from the successful call
}
})
.catch((err) => {
console.log(chalk.red(err))
reject(err)
})
})
}
您的 more_items_in_collection 案例永远不会解决承诺。 它只是创建一个新的,然后什么都不做。
此外,您通过使用new Promise
使您的代码变得比它需要的更复杂。 Axios 已经返回了一个 promise,所以没有必要显式地创建一个新的 promise。 调用.then
将自动创建一个新的 promise,它会解析为您在回调中返回的任何值。
const queryPipeDrive = (start) => {
// API CALL
return axios({
method: "GET",
url: pipeDriveURI,
params: {
api_token: apiKey,
start: start,
},
})
// THEN DO THIS
.then((response) => {
// IF there are more items in collection on additional pages, iterate through the pages
if (response.data.additional_data.pagination.more_items_in_collection) {
// Add all deals on page to the container
for (const deal of response.data.data) {
db.get("deals").push(deal); // Push deal data to the StormDB File
}
console.log(
chalk.cyan(`${response.data.additional_data.pagination.next_start}`)
);
// Function loop created. We will loop UNTIL the 'more_items_in_collection' prop is false, then we'll resolve the promise.
return queryPipeDrive(
response.data.additional_data.pagination.next_start
);
} else {
// Add all deals on this page to the reponse container
for (const deal of response.data.data) {
db.get("deals").push(deal);
}
db.save(); // Save changes to temp DB
return response.data.data;
}
})
.catch((err) => {
console.log(chalk.red(err));
throw err;
});
};
除了接受的答案。
你会考虑在 await 中使用这个异步函数吗? 通过这种方式,您可以调用main()
。
const main = async start => {
const res = await queryPipeDrive(start);
if (res.isMoreItems === true) {
await main(res.nextStart);
}
};
async function queryPipeDrive(start) {
const response = await axios({
method: "GET",
url: pipeDriveURI,
params: {
api_token: apiKey,
start: start,
},
});
for (const deal of response.data.data) {
db.get("deals").push(deal);
}
if (response.data.additional_data.pagination.more_items_in_collection) {
console.log(
chalk.cyan(`${response.data.additional_data.pagination.next_start}`)
);
return {
isMoreItems: true,
nextStart: response.data.additional_data.pagination.next_start,
};
} else {
db.save(); // Save changes to temp DB
return {
isMoreItems: false,
};
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.