承诺永远不会解决 - NodeJS

Promise never settles - NodeJS

我做了以下循环,我在其中循环了一个数组;然后对它们中的每一个进行快速 GET 请求。

我使循环工作并且数据被正确记录。然而,“循环”永远不会结束,因此不会到达 ().then => {}

Promise.all(
    arr.map((key,item) => {
    return new Promise((resolve,reject) => {
        var costmicro = 0;
        request.post({
            url: 'https://googleads.googleapis.com/v8/customers/'+arr[item]+'/googleAds:searchStream',
            headers: {
                'Content-Type': 'application/json',
            },
            json: {
                "query": "SELECT metrics.cost_micros FROM campaign WHERE segments.date DURING LAST_30_DAYS",
            }
            }, function (errAdsCampaign, httpResponseAdsCampaign, bodyAdsCampaign) {
                if (!errAdsCampaign) {
                for (ii in bodyAdsCampaign[0].results) {
                    costmicro = costmicro+parseInt(bodyAdsCampaign[0].results[ii].metrics['costMicros']);
                    var arrlength = bodyAdsCampaign[0].results.length-1;
                        if (ii == arrlength) {
                            objectArray.push({name: arr[item], cost: costmicro / 1000000});
                            resolve(objectArray);
                        }
                }
            } else {
                reject();
            }
        });
    });
    })
).then(()=>{
    console.log('done');
    console.log(objectArray)
}).catch(() => {
    console.error;
});

更新 替换了 catch() 函数。像这样;遗憾的是,它从未 returns 出错,也从未完成

}).catch((e) => {
    console.error(e);
});

非常感谢任何帮助!

您在循环内的代码可能会引发错误,它会跳过 .then() 子句并转到 .catch() 子句。您可以将 .catch() 子句替换为以下代码以查看遇到了什么错误。

}).catch((e) => {
    console.error(e);
});

在循环内的函数中,您需要考虑所有可能的退出路径并调用 resolve()reject()。一个这样的未处理的退出路径是如果 bodyAdsCampaign[0].results 是一个空数组或未定义。在这种情况下,函数将完成 运行 而不会调用 resolve()reject().

您还可以在 function (errAdsCampaign, httpResponseAdsCampaign, bodyAdsCampaign) 回调函数的末尾添加对 reject() 的调用,以捕获函数中未处理的所有场景。

request 已被弃用。参考https://www.npmjs.com/package/request

相反,我建议使用 axios

(async function run() {
  try {
    const objectArray = await Promise.all(
      arr.map(async (key, item) => {
        const res = await axios.post(
          "https://googleads.googleapis.com/v8/customers/" +
            arr[item] +
            "/googleAds:searchStream",
          {
            json: {
              query:
                "SELECT metrics.cost_micros FROM campaign WHERE segments.date DURING LAST_30_DAYS",
            },
          },
          {
            headers: {
              'Content-Type': 'application/json',,
            },
          }
        );

        const costmicro = res.data.bodyAdsCampaign.results.reduce((acc, cur) => {
          acc += cur.metrics["costMicros"];
          return acc;
        }, 0);

        return { name: arr[item], cost: costmicro / 1000000 };
      })
    );

    console.log(objectArray);
  } catch (err) {
    console.log(err);
  }
})();