我已经看过并尝试过$ .when和$ .Deferred的六种变体,但我无法让它正常工作。下面的代码应该做到以下几点:
1。)用户点击登录,调用登录功能。
2。)登录调用renderNavbar,它需要从服务器执行回调。
3.。)renderNavbar检索到数据后,在renderNavbar设置了#navbar的html属性后,login应该调用toggleLoginState。
实际发生的是登录调用renderNavbar然后立即调用toggleLoginState而不等待renderNavbar内的回调。我该如何解决?? (BTW renderNavbar和toggleLoginState在代码中的其他地方彼此独立调用。一个人不能直接调用另一个。)。
var app = {
this.login = function () {
$.when(app.renderNavbar()).done(app.toggleLoginState(1)); // wrong does not work
}
this.renderNavbar = function ()
{
return $.when($.get('/Home/Navbar')).done(function (data) {
$('#navbar').html(data); // this line must complete before the call the to toggleLoginState is made
});
}
this.toggleLoginState = function (state)
{
if (state == 1) {// yada} // this line should execute after #navbar is set
}
}
答案 0 :(得分:1)
您无需在代码中的任何位置使用$.when
。 $.get
会返回一个可以直接调用done
的承诺。你只是再次承诺这个承诺。从renderNavbar
返回相同的承诺,并使用$.when
将其包裹在第三时间。
实际的潜在问题是你没有将回调函数传递给done
,你只是立即调用代码并将返回值传递给done
。
您的代码应该如下所示,将函数传递给done
:
this.renderNavbar = function () {
return $.get('/Home/Navbar').done(function (data) {
$('#navbar').html(data); // this line must complete before the call the to toggleLoginState is made
});
}
this.login = function () {
app.renderNavbar().done(function () {
app.toggleLoginState(1));
});
}
不同之处在于你正在这样做....
// invoke doSomething() immediately, pass return value to done
$(...).done(doSomething())
当你需要这样做时:
// give done a function to invoke in the future
$(...).done(function () { doSomething() });