简体   繁体   English

Promise 解决得太早

[英]Promise resolving too early

I'm having an issue where my Promise.all is resolving too early.我遇到了一个问题,我的 Promise.all 解决得太早了。 For a test I want to console.log the length of the array which is getting pushed from within the promise map but it is returning 0 sadly.对于测试,我想控制台记录从 promise map 中推送的数组的长度,但遗憾的是它返回 0。 I'm sure it's something simple...我确定这很简单...

fromPath(job.data.path, { density: 100, format: "png" }).bulk(-1, true).then(output => {
  Promise.all(output.map(page => 
    jimp.read(Buffer.from(page.base64, 'base64')).then(img => 
      {
        img.invert().getBase64Async(jimp.AUTO).then(data => imageArray.push(data.replace('data:image/png;base64,', ''))).catch(err => console.log(err))
      }
      ).catch(err => console.log(err))
      )).catch(err => console.log(err))
}
  // This returns early
).then(console.log(imageArray.length)).then(done()).catch(err => console.log(err));

Any help would be greatly appreciated.任何帮助将不胜感激。

There are a lot of issues there.那里有很多问题。 Mainly they fall into these categories:它们主要分为以下几类:

  • Not returning the results of promise chains from fulfillment handlers, which means the chain the fulfillment handler is in won't be linked up to the promise chain you created within it不从履行处理程序返回 promise 链的结果,这意味着履行处理程序所在的链不会链接到您在其中创建的 promise 链
  • Calling functions and passing their return value into then , rather than passing a function into then调用函数并将它们的返回值传递给then ,而不是将 function 传递给then

See inline comments in this minimal, least-changes reworking of that code:请参阅该代码的这个最小的、最少更改的修改中的内联注释:

fromPath(job.data.path, { density: 100, format: "png" }).bulk(-1, true)
.then(output => {
    // Return the result of `Promise.all`
    return Promise.all(
        output.map(
            page => jimp.read(Buffer.from(page.base64, 'base64'))
                .then(img => {
                    // Return the ersult of this promise chain
                    return img.invert().getBase64Async(jimp.AUTO)
                    .then(data => imageArray.push(data.replace('data:image/png;base64,', '')))
                    // This error handler does nothing useful, since we now return
                    // the promise chain
                    // .catch(err => console.log(err))
                })
                // Recommend **not** handling errors at this level, but using
                // `Promise.allSettled` instead
                .catch(err => console.log(err))
        )
    )
    // This will only be reached if a *synchronous* error occurs calling (for instance)
    // `getBase64Async`, since you've already caught errors above
    .catch(err => console.log(err))
})
// Use a function here, don't call `console.log` directly
.then(() => console.log(imageArray.length))
//    ^^^^^^
// Pass `done` directly to `then`, don't call it and pass its return value
// (e.g., remove the `()`)
.then(done) // Or `.then(() => done)` if you want `done` called with no arguments
.catch(err => console.log(err));

FWIW, though, if I had to not use async functions I'd probably do it like this:不过,FWIW,如果我不得不不使用async函数,我可能会这样做:

fromPath(job.data.path, { density: 100, format: "png" }).bulk(-1, true)
.then(output => Promise.allSettled(
    output.map(
        page => jimp.read(Buffer.from(page.base64, 'base64'))
            .then(img => img.invert().getBase64Async(jimp.AUTO))
            .then(data => {
                imageArray.push(data.replace('data:image/png;base64,', ''));
            })
    )
))
.then(results => {
    // Show errors
    const errors = results.filter(({status}) => status === "rejected");
    for (const {reason} of errors) {
        console.error(reason);
    }
    // Done
    done();
});

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM