无法从异步方法返回

时间:2016-08-09 08:26:08

标签: 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 = 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
  }
};

回到我的window.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.loadedImage返回,是不是在某种程度上还不够?

1 个答案:

答案 0 :(得分:4)

spawn没有return,因此返回undefined,您将其分配给drawImage。您无法从异步调用的函数返回 - return处理程序内的this.loadedImage.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);
});

与面向对象无关,而且与"How do I return the response from an asynchronous call?"没有答案的事实有关。

编辑

编辑

  

我有一个明确的smwo.loadedImage返回,是不是在某种程度上还不够?

没有。 spawn会将该函数分配给处理程序,然后返回undefined。浏览器稍后会触发load事件,调用处理函数,然后将drawImage返回给浏览器,浏览器将丢弃它而不会产生影响(如果它是click处理程序,例如,浏览器将使用此返回值来决定是否考虑处理的click事件;使用load事件则无关紧要)。但是这个价值永远不会达到你的代码。

编辑因为忘记this上下文切换

而愚蠢