Javascript 无法从异步方法返回
我试图为绘制到html画布中的实体定义一个类。该类被定义为: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
//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
insidethis.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问题。抱歉我的困惑。实体正在按预期加载。