JS Promise 等待嵌套异步函数

JS Promise wait for nested asynchronous function

我在正确计时 2 个异步操作时遇到问题,因此外部函数会等待内部函数完成后再继续。我尝试实施的解决方案基于使用 ES2015 的现有解决方案,因此我无法使用 await,必须使用 Promises。

解决方案分为多个 classes,为了便于概述,我将其称为 Main、Invoker 和 Inner。因此 Main class 使用 Invoker 的实例异步执行来自 Inner class 的命令,然后应该等待响应,这有效但它不等待异步 Image.onload() 来自内部 class.

的 setSize()
class Inner extends Component{
    setSize(size){
        const newImage = { url: null, imageName: canvasImage.imageName};
        
        ... some stuff...
        const tempImage = new Image();
        tempImage.src = canvas.toDataURL();
        tempImage.onload = function(){
        
            ... some stuff...
            const tempCanvas = document.createElement("canvas");
            const tempCtx = tempCanvas.getContext("2d");
            tempCtx.drawImage(image, x, y, xa, ya);

            newImage.url = tempCanvas.toDataURL();
        }
        return Promise.resolve(newImage);
    }
}


class Main{
    resize(size){
        imageData = this.execute(commandName,'setSize', size);
        
        imageData.then(image => {
            ... do stuff with image data...
        });
    }
    execute(commandName, ...args) {
        return this._invoker.execute(commandName, ...args);
    }
}

class Invoker{
    execute(...args) {

        let [command] = args;
        if (isString(command)) {
          command = commandFactory.create(...args);
        }

        return this._invokeExecution(command).then((value) => {
          this.clearRedoStack();

          return value;
        });
    }
}

我已经尝试在 onload 函数内的 setSize 函数中移动“return Promise.resolve(newImage),但是由于缺少解决。 有什么想法吗?

您需要 return 承诺并在 onload 中解决它。

setSize () {
  return new Promise((resolve, reject) => {
    ...
    tempImage.onload = function () {
      ...
      resolve(newimage)
    }
  })
}

因为 setSize 函数在 onload 中使用基于回调的语法,您需要等到 onload 函数被浏览器调用,

您可以 return 来自 setSize 的承诺,并处理 onloadresolveonerrorreject 的处理,例如:

setSize(size){
    return new Promise((res, rej) => {
      const newImage = { url: null, imageName: canvasImage.imageName};
      
      ... some stuff...
      const tempImage = new Image();
      tempImage.src = canvas.toDataURL();
      tempImage.onload = function(){
      
          ... some stuff...
          const tempCanvas = document.createElement("canvas");
          const tempCtx = tempCanvas.getContext("2d");
          tempCtx.drawImage(image, x, y, xa, ya);

          newImage.url = tempCanvas.toDataURL();
          res(newImage);
      }
      tempImage.onerror = function(error) {
        rej(error)
      }
    })
}