You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Promise/async场景中正确更新this指向的属性或内部变量

问题原因

img.onload 是普通函数作为事件回调,执行时this默认指向触发事件的img实例,而非embedFromString方法所属的外层对象,所以你赋值的属性实际都挂在了img对象上,自然不会更新到目标对象上。

解决方案

共有3种常用的修复方式:

方案1:外层提前缓存this指向

兼容性最好的写法,在函数开头把外层的this存到临时变量中,回调内直接用临时变量操作属性:

embedFromString: function(url, mediaType) {
  const that = this; // 提前缓存外层this指向
  let img = new Image,
    canvas = document.createElement("canvas"),
    ctx = canvas.getContext("2d"),
    src = url;
  let imgBase64;
  img.crossOrigin = "Anonymous";
  img.src = src;
  return new Promise(((resolve, reject) => {
    img.onload = async function() {
      canvas.width = img.width;
      canvas.height = img.height;
      ctx.drawImage(img, 0, 0);
      imgBase64 = canvas.toDataURL("image/png");
      console.log(imgBase64, 'hello');
      // 用缓存的that操作外层对象属性
      that.mediaType = mediaType;
      that.url = imgBase64.split(',')[1];
      that.base64 = true;
      return resolve();
    }
  }));
}

方案2:用箭头函数作为onload回调

箭头函数不会绑定自身的this,会自动继承外层作用域的this指向:

embedFromString: function(url, mediaType) {
  let img = new Image,
    canvas = document.createElement("canvas"),
    ctx = canvas.getContext("2d"),
    src = url;
  let imgBase64;
  img.crossOrigin = "Anonymous";
  img.src = src;
  return new Promise(((resolve, reject) => {
    // 回调改为箭头函数
    img.onload = async () => {
      canvas.width = img.width;
      canvas.height = img.height;
      ctx.drawImage(img, 0, 0);
      imgBase64 = canvas.toDataURL("image/png");
      console.log(imgBase64, 'hello');
      this.mediaType = mediaType;
      this.url = imgBase64.split(',')[1];
      this.base64 = true;
      return resolve();
    }
  }));
}

方案3:用bind方法绑定this

通过bind方法手动把回调的this绑定为外层的this:

embedFromString: function(url, mediaType) {
  let img = new Image,
    canvas = document.createElement("canvas"),
    ctx = canvas.getContext("2d"),
    src = url;
  let imgBase64;
  img.crossOrigin = "Anonymous";
  img.src = src;
  return new Promise(((resolve, reject) => {
    img.onload = (async function() {
      canvas.width = img.width;
      canvas.height = img.height;
      ctx.drawImage(img, 0, 0);
      imgBase64 = canvas.toDataURL("image/png");
      console.log(imgBase64, 'hello');
      this.mediaType = mediaType;
      this.url = imgBase64.split(',')[1];
      this.base64 = true;
      return resolve();
    }).bind(this); // 绑定外层this到回调函数
  }));
}

内容的提问来源于stack exchange,提问作者Parul

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.02 09:45:02