首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >UnhandledPromiseRejectionWarning: TypeError:对象是不可迭代的。使用时等待Promise.all(承诺);

UnhandledPromiseRejectionWarning: TypeError:对象是不可迭代的。使用时等待Promise.all(承诺);
EN

Stack Overflow用户
提问于 2020-10-13 12:14:20
回答 1查看 1.8K关注 0票数 0

我正在尝试用NodeJS异步生成PNG。

代码语言:javascript
复制
async generateAnnualPNG(recap) {
    let promises = [];
    console.log("Generating images for annual reports")
    for (const meter of recap.meters) {
        const url = process.env.BASE_URL + "operations/" + recap.operation.name + "/meters/" + meter.prm + "/annual_individual_report";
        promises.push(this.makePngScreenshot(recap, url, meter.prm, "annual_2019-2020"));
    }
    return promises
},

makePngScreenshot

代码语言:javascript
复制
async makePngScreenshot(recap, url, meterId, filename) {
        axios.get(url, null); // Make the request to generate html page
        const destination = "public/images/" + recap.operation.name + "/" + recap.date_ini + "_" + recap.date_end + "/" + meterId
        return new Pageres({ delay: 2, filename: filename })
            .src(url, ['1300x650'], { crop: true })
            .dest(destination)
            .run()

    }

当我调试时,我可以看到返回的承诺似乎没有问题,它是一个由7个挂起的承诺组成的数组。

我称它为:

代码语言:javascript
复制
module.exports = {

    async generatePNGs(recap) {
        let promises = [];
        promises = this.generateAnnualPNG(recap)

        await Promise.all(promises);
        console.log("Done generating images")
    },

我从没见过Done generating images留言..。为什么?

这是日志:

代码语言:javascript
复制
Generating images for annual reports
images.js:53
(node:571426) UnhandledPromiseRejectionWarning: TypeError: object is not iterable (cannot read property Symbol(Symbol.iterator))
    at Function.all (<anonymous>)
    at Object.generatePNGs (/home/julien/Code/customer_recap/images.js:17:34)
    at init (/home/julien/Code/customer_recap/index.js:113:44)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
<node_internals>/internal/process/warning.js:32
(node:571426) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
<node_internals>/internal/process/warning.js:32
(node:571426) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-10-13 23:22:00

promises generatePNGs 中的实际上不是一个数组,它是一个 Promise<Array>**.**,您可以等待它,但是您可能应该从generateAnnualPNG中删除async

代码语言:javascript
复制
async makePngScreenshot(recap, url, meterId, filename) {
  /* ... */
  return new Pageres(/*...*/).src(/*...*/).dest(/*...*/).run()
}

makePngScreenshotasync,因此它绝对返回一个Promise

代码语言:javascript
复制
async generateAnnualPNG(recap) {
    let promises = [];
    /* ... */
    for (const meter of recap.meters) {
        const url = /* ... */
        promises.push(this.makePngScreenshot(/* ... */));
    }
    return promises
}

generateAnnualPNG也是async,所以它绝对会返回一个承诺。显然,该承诺将解析为一组承诺,因为它填充了makePngScreenshot返回的对象的数组。

这意味着,尽管您将promises设置为一个数组,但实际上您已经将其设置为一个承诺。

代码语言:javascript
复制
async generatePNGs(recap) {
  let promises = [];                         // this was an array
  promises = this.generateAnnualPNG(recap)   // but now it's a promise

  await Promise.all(promises);
  console.log("Done generating images")
}

你最好的选择是将asyncgenerateAnnualPNG的定义中删除。尽管它正在处理承诺,但它并不是在执行任何承诺,到那时,generateAnnualPNG将返回一系列承诺,而不是(承诺)数组的承诺。该列表将按generatePNGs预期的方式工作,您可以像上面那样将该数组直接传递到Promise.all中。

作为另一种选择,您还可以将generatePNGs更改为await this.generateAnnualPNG(/* ... */),只有在您的列表还没有同步准备好(也就是说,您不知道返回的列表中有多少承诺)时,才需要这样做。在这一点上,返回一系列承诺的价值非常小;您可以在await promises中使用generateAnnualPNG,这样generateAnnualPNG的返回值就是对一个值数组的承诺。唯一不这样做的原因是,如果您有UI或日志记录,它将从显示增量进度中获益。

最后注意:看起来makePngScreenshot也是async,实际上没有任何await。如果这是当前代码中的错误,请不要忘记在需要时添加await (例如,添加到axios.get调用中)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64335066

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档