首页 > 解决方案 > Node.js - 承诺不在循环内解决

问题描述

大家好,

我正在使用 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)
     })
 })

}

标签: javascriptnode.jspromisees6-promise

解决方案


您的 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;
    });
};

推荐阅读