在面向对象语言的背景下,我试图学习一些jquery,并围绕异步调用。我的目的是创建一个javascript对象来包含异步api调用的结果,并且能够询问所述对象是否已完成加载。
我一直在尝试使用来自jquery的Deferred来做这件事,我没有问题让片段像文档中的示例一样工作,但它不会按照我期望的顺序执行把延期放在我的班级里。
如何使用$ .Deferred创建javascript对象作为成员变量?
(我附加的代码中的超时是模仿api调用的延迟)
<!DOCTYPE html>
<html>
<body>
<script src="jquery-3.1.1.js"></script>
<script>
//top level
var isdone = false;
var def = $.Deferred();
$.when(def).done(function() {
var msg = "checking topLevel isdone " + isdone;
console.log(msg);
$("body").append("<p>" + msg + "</p>");
})
var delayedCall = function() {
setTimeout(function() {
//resolve after 5 seconds
isdone = true;
def.resolve();
}, 1000);
}
delayedCall();
//inside function
function DelayedObject()
{
this.defThis = $.Deferred();
var defVar = $.Deferred();
this.delayedObjCall = function()
{
setTimeout(function()
{
//resolve after 5 seconds
isdone = true;
this.def.resolve();
}, 1000);
}
this.delayedObjCall();
this.getStatusThis = function()
{
return this.def;
}
this.getStatusVar = function()
{
return this.def;
}
}
delObj = new DelayedObject();
$.when(delObj.getStatusThis() ).done(function() {
var msg = "checking delObj (this) isdone " + isdone;
console.log(msg)
$("body").append("<p>" + msg + "</p>");
});
$.when(delObj.getStatusVar() ).done(function() {
var msg = "checking delObj (var) isdone " + isdone;
$("body").append("<p>" + msg + "</p>");
console.log(msg)
});
$(window).on("load", function()
{
var msg = "<p>" + " Page loaded " + "</p>";
$("body").append(msg);
console.log(msg);
});
</script>
</body>
</html>
结果
checking delObj (this) isdone false
checking delObj (var) isdone false
Page loaded
checking topLevel isdone true
答案 0 :(得分:1)
一些问题:
您在某些地方引用了错误的对象/变量(this.def
不存在,this.defThis
和defVar
从未使用过)
this
未在超时回调函数中定义(或者在草率模式下为window
),因此您需要使用解决方案(多种可能性,例如bind
})
您永远不会解决defVar
您使用了一个isdone
变量,因此请注意,一旦设置为true
,它仍为true
并且对其他承诺几乎没有说明。
以下是更正后的代码(简化:省略文档内容的更改):
var isdone = false;
var def = $.Deferred();
$.when(def).done(function() {
console.log("checking topLevel isdone " + isdone);
isdone = false; // set back to false
});
var delayedCall = function() {
setTimeout(function() {
isdone = true;
def.resolve();
}, 500); // Half a second
}
delayedCall();
//inside function
function DelayedObject() {
this.defThis = $.Deferred();
var defVar = $.Deferred();
this.delayedObjCall = function() {
setTimeout(function() {
//resolve after 5 seconds
isdone = true;
this.defThis.resolve(); // refer to the correct object
}.bind(this), 1000); // provide the correct context with bind
// Also resolve the other deferred:
setTimeout(function() {
//resolve after 5 seconds
isdone = true;
defVar.resolve();
}.bind(this), 1500); //... a bit later
}
this.delayedObjCall();
this.getStatusThis = function() {
return this.defThis; // return correct object
}
this.getStatusVar = function() {
return defVar; // return correct object
}
}
delObj = new DelayedObject();
$.when(delObj.getStatusThis() ).done(function() {
console.log("checking delObj (this) isdone " + isdone);
isdone = false; // set back to false
});
$.when(delObj.getStatusVar() ).done(function() {
console.log('checking delObj (var) isdone ' + isdone)
isdone = false; // set back to false
});
$(window).on("load", function() {
console.log('Page loaded');
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
&#13;