ES6传递DataURI作为输入-返回未定义

时间:2018-07-17 10:46:15

标签: javascript asynchronous ecmascript-6 data-uri

我试图将图像dataURI作为输入从URL链接传递到图像。我知道要这样做,我必须使用画布并从那里进行转换。但是,由于这是一种“异步”方法,因此我无法产生任何回报。

    getLogo() {
    let image = new Image();
    let canvas = document.createElement('canvas');
    return new Promise((resolve) => {
      image.onload = () => {
        canvas.width = image.naturalWidth;
        canvas.height = image.naturalHeight;
        canvas.getContext('2d').drawImage(image, 0, 0);
        let uri = canvas.toDataURL('image/png');
        resolve(uri);
      };
      image.src = this.logo;
    });
  }

  getLogoURI() {
    this.getLogo().then((result) => {
      console.log(result); // the correct output writes here
      return result; // this returns undefined
    });
  }

然后从需要URI的类中调用它,这在for循环内。

let logo = tariff.getLogoURI();

我相信在调用getLogoURI()时,这会自动将其视为同步函数,因此不会返回正确的值,但是我不确定。

1 个答案:

答案 0 :(得分:0)

让我解释一下getLogoURI方法的当前工作方式

getLogoURI() {
  // when getLogoURI() is invoked, it calls getLogo()
  // getLogo() returns a promise,
  // whose then is being invoked with a success callback, which will be invoked on resolving of promise
  // then() function returns a promise which is not being returned by getLogoURI() method
  // so getLogoURI() method is not returning anything
  // if a function do not return any thing then undefined is returned by default
  // that's why you are receiving undefined
  this.getLogo().then((result) => {
    console.log(result); // the correct output writes here
    return result; // this returns undefined
  });
}

为解决这个问题,我们可以进行一些更改

getLogoURI() {
  // return promise being returned by then()
  return this.getLogo().then((result) => {
    console.log(result); // the correct output writes here
    return result; // this returns undefined
  });
}

现在getLogoURI将返回一个诺言,我们可以这样使用它

getLogoURI().then(result => //use result here);

等等,这是我们在getLogoURI中已经完成的工作,这意味着getLogoURI只是一个无用的包装程序,您不需要使用它。您尝试实现的方法是不可能的,因为这些是可以同步完成的异步操作。希望阅读MDN的documentation对您有所帮助。

您可以使用async / await来简化控制流,它看起来很像同步流,但它纯粹是异步的。谨慎使用它可能与某些浏览器存在兼容性问题。使用async / await,您上面的代码将如下所示:

async useLogoURI() {
  let logo = await this.getLogo();
  // use logo here
}