簡體   English   中英

Promise 解決得太早

[英]Promise resolving too early

我遇到了一個問題,我的 Promise.all 解決得太早了。 對於測試,我想控制台記錄從 promise map 中推送的數組的長度,但遺憾的是它返回 0。 我確定這很簡單...

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));

任何幫助將不勝感激。

那里有很多問題。 它們主要分為以下幾類:

  • 不從履行處理程序返回 promise 鏈的結果,這意味着履行處理程序所在的鏈不會鏈接到您在其中創建的 promise 鏈
  • 調用函數並將它們的返回值傳遞給then ,而不是將 function 傳遞給then

請參閱該代碼的這個最小的、最少更改的修改中的內聯注釋:

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,如果我不得不不使用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