【问题标题】:JS Promise wait for nested asynchronous functionJS Promise 等待嵌套的异步函数
【发布时间】:2021-03-30 06:16:37
【问题描述】:

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

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

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)”,但是由于缺少解析,我在调用程序中遇到错误。 有什么想法吗?

【问题讨论】:

  • 你需要使用new Promise,而不是Promise.resolve,来创建一个通过onload回调实现的promise。

标签: javascript promise


【解决方案1】:

由于setSize函数使用基于回调的语法onload,您需要等到浏览器调用onload函数,

您可以从setSize 返回一个承诺,并为resolve 处理onload,为reject 处理onerror,类似于:

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

【讨论】:

    【解决方案2】:

    你需要返回一个promise并在onload中解决它。

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

    【讨论】:

    • 谢谢!您的回答和来自 oieduardorabelo 的回答帮助了!
    猜你喜欢
    • 1970-01-01
    • 2020-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-04
    • 1970-01-01
    相关资源
    最近更新 更多