当我调用此函数时,它会立即返回结果,而不是在第三个promise之后延迟。我该怎么办?
getBlogs: function(blogId){
var blogcomments = new Entities.BlogCommentCollection();
var blogs = new Entities.BlogCollection();
var defera = $.Deferred();
var deferb = $.Deferred();
var deferc = $.Deferred();
var model;
//alert(model);
$.get("/lightning/presentation/blogs", function(val){
defera.resolve(val);
});
var promisea = defera.promise();
$.when(promisea).done(function(val){
var models = initializeBlogs(JSON.parse(val));
blogs.reset(models);
model = blogs.at(blogId);
//alert(JSON.stringify(model));
$.get("/lightning/presentation/blogs/?blogId=" + blogId, function(full){
deferb.resolve(full);
});
});
var promiseb = deferb.promise();
$.when(promiseb).done(function(full){
model.set('full', full);
//alert(JSON.stringify(model));
$.get("/lightning/presentation/blogs/?comments=" + blogId, function(res){
deferc.resolve(res);
});
});
var promisec = deferc.promise();
$.when(promisec).done(function(res){
if(res.length === 0){
blogcomments.reset();
}else{
//alert(res)
var models = initializeBlogComments(JSON.parse(res));
blogcomments.reset(models);
model.set('comments', blogcomments)
//return model;
}
currentBlog = model;
alert(JSON.stringify(model));
//return model;
});
//alert(JSON.stringify(model));
return model;
},
答案 0 :(得分:1)
Promise是异步的。它们不会导致当前函数延迟返回(这将是同步)。他们回来了,这是一个将来会在某个时刻解决的承诺。
因此修复代码的最基本方法是不返回模型,而是返回承诺
getBlogs: function(blogId) {
var deferAll = $.Deferred();
// your last set will then respond to them all
$.when(promisec).done(function(res){
if(res.length === 0){
blogcomments.reset();
}else{
//alert(res)
var models = initializeBlogComments(JSON.parse(res));
blogcomments.reset(models);
model.set('comments', blogcomments)
//return model;
}
currentBlog = model;
// THIS is where it gets resolved
deferAll.resolve(model);
});
// do whatever you need to
return deferAll.promise();
}
然后将getBlogs称为
getBlogs(25).then(function(model) {
// model is given here
});
但是,有更好的方法可以做到这一点。首先,你可以链接承诺。
$.get("/lightning/presentation/blogs/?blogId=" + blogId).then(function(full){...}).then().then() // etc
最后,如果你真的要按照这样的顺序做多个异步事情,我可以推荐一下caolan优秀的异步库吗?这使得这样的思考变得更加容易。 https://github.com/caolan/async
答案 1 :(得分:1)
getBlog: function(blogId, model){
var blogcomments = new Entities.BlogCommentCollection();
var defer = $.Deferred();
var fullBlog;
$.when(
$.get("/lightning/presentation/blogs/?blogId=" + blogId, function(full){
fullBlog = full;
}),
$.get("/lightning/presentation/blogs/?comments=" + blogId, function(res){
var models = initializeBlogComments(JSON.parse(res));
blogcomments.reset(models);
})
).done(function() {
model.set('full', fullBlog);
model.set('comments', blogcomments);
defer.resolve(model);
});
return defer.promise();
},
答案 2 :(得分:0)
改进你已经提供的答案,你可以这样做,避免创建额外的延期,只使用$.when()
已经返回的承诺。 :
getBlog: function(blogId, model){
var blogcomments = new Entities.BlogCommentCollection();
var fullBlog;
return $.when(
$.get("/lightning/presentation/blogs/?blogId=" + blogId, function(full){
fullBlog = full;
}),
$.get("/lightning/presentation/blogs/?comments=" + blogId, function(res){
var models = initializeBlogComments(JSON.parse(res));
blogcomments.reset(models);
})
).then(function() {
model.set('full', fullBlog);
model.set('comments', blogcomments);
return model;
});
},
或者,您还可以使用$.when()
的返回值来避免单独的ajax回调,如下所示:
getBlog: function(blogId, model){
var blogcomments = new Entities.BlogCommentCollection();
return $.when(
$.get("/lightning/presentation/blogs/?blogId=" + blogId),
$.get("/lightning/presentation/blogs/?comments=" + blogId)
).then(function(r1, r2) {
model.set('full', r1[0]);
var models = initializeBlogComments(JSON.parse(r2[0]));
blogcomments.reset(models);
model.set('comments', blogcomments);
return model;
});
},