Javascript 无法从异步方法返回

Javascript 无法从异步方法返回,javascript,canvas,Javascript,Canvas,我试图为绘制到html画布中的实体定义一个类。该类被定义为: //classes for smallworld var Smwo = function (num1,num2,num3,bool1,num4,imageL) { this.posX = num1, this.posY = num2, this.margin = num3, this.blocking = bool1, this.intercept = num4, this.imageLink = image

我试图为绘制到html画布中的实体定义一个类。该类被定义为:

//classes for smallworld

var Smwo = function (num1,num2,num3,bool1,num4,imageL)
{
  this.posX = num1,
  this.posY = num2,
  this.margin = num3,
  this.blocking = bool1,
  this.intercept = num4,
  this.imageLink = imageL,
  this.spawn = function(xer,yer)
  {
    var randX = Math.floor(Math.random() * xer);
    var randY = Math.floor(Math.random() * yer);
    this.posX = randX;
    this.posY = randY;
    this.loadedImage = new Image();
    this.loadedImage.onload = function()
    {
      //register as live actor
      console.log("Loaded");
      return this.loadedImage;
      console.log(this.loadedImage);
    }
    this.loadedImage.src = this.imageLink;
  },
  this.act = function()
  {
    //unit behaviours
  },
  this.tick = function()
  {
    //unit lifecycle
  }
};
回到我的窗口。启动所有内容的onload,然后我尝试:

//spawn test
smallWorld.newTree = new Smwo(10,10,10,true,5,"tree.png");
var drawImage  = smallWorld.newTree.spawn(cWi,cHi);
console.log(smallWorld.newTree);
console.log(drawImage);
context.drawImage(drawImage,10,10);
smallWorld是我的全局名称空间,我也尝试过删除这个名称空间,得到了相同的结果。我的控制台输出显示我正在构建一个新的Smwo实例,但是drawImage被认为是未定义的,因此context.drawImage失败,因为第一个传递的变量不是映像类型


我错过了什么?我有一个smwo.LoadeImage的显式返回,这还不够吗?

spawn
没有
返回
,因此返回您分配给
drawImage
未定义的
。无法从异步调用的函数返回-
return
inside
this.loadeImage.onload
处理程序不会执行您想要的操作

你要么想要承诺,要么想要回电。这是最简单的修复方法:

this.spawn = function(xer,yer,callback)
  {
    var randX = Math.floor(Math.random() * xer);
    var randY = Math.floor(Math.random() * yer);
    this.posX = randX;
    this.posY = randY;
    this.loadedImage = new Image();
    this.loadedImage.onload = function() // `this` here is `this.loadedImage`
    {
      //register as live actor
      console.log("Loaded");
      callback(this);
    }
    this.loadedImage.src = this.imageLink;
  }
然后

var drawImage  = smallWorld.newTree.spawn(cWi,cHi, function(drawImage) {
    console.log(smallWorld.newTree);
    console.log(drawImage);
    context.drawImage(drawImage,10,10);
});
与面向对象无关,与没有答案的事实有关

编辑您的编辑:

我有一个smwo.LoadeImage的显式返回,这还不够吗

否。
spawn
将把该函数分配给处理程序,然后返回
undefined
。浏览器将在一段时间后触发
load
事件,调用handler函数,然后您将
drawImage
返回到浏览器,浏览器将丢弃它而不生效(例如,如果是<代码>点击< /代码>处理程序,浏览器将使用这个返回值来决定是否考虑点击事件是否处理;使用<代码>加载< /代码>事件是无关的)。但是这个值永远不会达到您的代码。


编辑因为忘记
这个
上下文开关是愚蠢的

返回this.loadedImage;是返回this.loadedImage.onload不产生,这是分配给this.loadedImage.onload的函数,不是你的对象。我不明白画布有什么特别之处吗?@Pavlo:不-代码需要用于代码审阅。@Amadan yo你是对的。这个问题把我弄糊涂了:我以为这是关于在JS中应用OOP原则。查看原型。在构造函数中为
this
分配函数是低效的,因为它会为每次调用构造函数创建一个新函数。请注意分配给this.loadeImage.onloadPerfect的函数中的这一点。非常感谢m我明白了,我应该使用更多的回调。我只是不习惯javascript still.EDIT中的计时。尽管它仍然不起作用。console.log(drawImage)仍然返回为未定义,并且上下文绘制仍然失败。啊…
这可能是问题所在;在处理程序中,
这将是加载的图像,因此
这。LoadeImage
将是加载图像的不存在的加载图像属性。请尝试
回调(this)
而不是
回调(这是loadeImage)
。或者使用
that=this
技巧,或者
bind
确保您知道
this
是什么。编辑:呜呜,我的大脑不工作,这么多更正:PWell done Amadan!额外的.loadedImage是不必要的,您是对的。这已经是您所指的。显然最后不是一个OO问题。抱歉我的困惑。实体正在按预期加载。