Javascript 需要在多次承诺后返回结果
当我调用这个函数时,它立即返回一个结果,而不是在第三个承诺之后延迟到。我能做什么Javascript 需要在多次承诺后返回结果,javascript,jquery,jquery-deferred,Javascript,Jquery,Jquery Deferred,当我调用这个函数时,它立即返回一个结果,而不是在第三个承诺之后延迟到。我能做什么 getBlogs: function(blogId){ var blogcomments = new Entities.BlogCommentCollection(); var blogs = new Entities.BlogCollection(); var defera = $.Deferred(); var deferb = $.Deferred(); var def
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;
},
承诺是异步的。它们不会导致当前函数延迟返回(即同步)。他们回报了一个承诺,这个承诺将在未来某个时候得到解决 因此,修复代码的最基本方法不是返回模型,而是返回承诺
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
最后,如果您真的要按这样的顺序执行多个异步操作,我可以推荐曹兰优秀的异步库吗?这使得这样的思考容易得多 改进您已经提供的答案,您可以这样做,避免创建额外的延迟,只需使用
$.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;
});
},
可能是重复的谢谢。我还找到了另一个选择,看看我的答案。我发现它是最小的:)当然,这也束缚了他们。
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;
});
},