I have an application where I'm pulling data from multiple sources, and only when all the data is pulled in, do I want to continue. I want the data as fast as possible so use parallel requests.
我有一个应用程序,我从多个来源提取数据,只有当所有数据都被拉入时,我是否要继续。我希望数据尽可能快,所以使用并行请求。
To figure out when all requests are done, I'm doing this:
为了弄清楚所有请求何时完成,我这样做:
function getData(cb) {
var count, data;
count = 0;
data = {};
function getDataDone() {
count++;
//only call callback when all async requests are done
if (count === 3 && cb) {
cb(data);
}
}
foo.doAsync({
success: function (d) {
data.foo = d;
getDataDone();
}
});
bar.doAsync({
success: function (d) {
data.bar = d;
getDataDone();
}
});
$.getJSON("/api/", function (d) {
data.user = d;
getDataDone();
});
} //end getData
getData(function (data) {
//application data loaded, do stuff
data.foo;
data.bar;
data.user;
});
foo.doAsync
, bar.doAsync
and $.getJSON
requests happen is parallel, when completed, they call getDataDone()
, which increments a counter. If the counter is equal to the expected number of requests, run callback.
foo.doAsync,bar.doAsync和$ .getJSON请求是并行的,完成后,它们调用getDataDone(),它会增加一个计数器。如果计数器等于预期的请求数,请运行回调。
How might jQuery.deferred be applied in this case? To code works perfectly OK as it is. Is there any benefit to using deferred over what I have?
在这种情况下如何应用jQuery.deferred?编码工作完全没问题。使用延迟比我有什么好处?
2 个解决方案
#1
4
var d1 = $.Deferred();
foo.doAsync({
success: function (d) {
data.foo = d;
d1.resolve();
}
});
var d2 = $.Deferred();
bar.doAsync({
success: function (d) {
data.bar = d;
d2.resolve();
}
});
var json_deferred = $.getJSON("/api/", function (d) {
data.user = d;
getDataDone();
});
$.when(d1, d2, json_deferred).then(function() {
alert('all requests finished');
});
Is there any benefit to using deferred over what I have?
使用延迟比我有什么好处?
Yep, deferreds allow more control on the app flow and usually (this case isn't an exception) provide more clear solutions.
是的,延迟允许更多地控制应用流程,并且通常(这种情况不是例外)提供更清晰的解决方案。
Hint: if you only need the result of asynchronous requests in the callback and nothing else - you may pass the result to the resolve
call like d1.resolve(d);
and then get it as a parameter of then()
callback, instead of using shared object as a temporary storage.
提示:如果您只需要回调中的异步请求结果而不需要其他内容 - 您可以将结果传递给解析调用,如d1.resolve(d);然后将其作为then()回调的参数,而不是使用共享对象作为临时存储。
In case of getJSON()
you could even omit the callback:
在getJSON()的情况下,您甚至可以省略回调:
var json_deferred = $.getJSON('/api/');
#2
1
Using jQuery.when: http://api.jquery.com/jQuery.when/ you can wait for several promises to finish.
使用jQuery.when:http://api.jquery.com/jQuery.when/你可以等待几个承诺完成。
You could wrap your doAsync()
methods in promises.
你可以将你的doAsync()方法包装在promises中。
function doAsync (opts) {
var msg = this.msg;
var data = { json: JSON.stringify({ msg: msg }) };
$.ajax("/echo/json/", {
type: "post",
data: data
}).then(opts.success);
}
var foo = { msg: "foo", doAsync: doAsync };
var bar = { msg: "bar", doAsync: doAsync };
function createPromise (doAsyncAble) {
var dfd = $.Deferred();
doAsyncAble.doAsync({
success: function (d) {
dfd.resolve(d);
}
});
return dfd.promise();
}
function getData(cb) {
var fooPromise = createPromise(foo);
var barPromise = createPromise(bar);
var apiPromise = $.ajax("/echo/json/", {
type: "post",
data: { json: JSON.stringify({ data: "api" }) }
});
$.when(fooPromise, barPromise, apiPromise).done(function (fooResponse, barResponse, apiResponse) {
var data = {};
data.foo = fooResponse;
data.bar = barResponse;
data.user = apiResponse[0];
cb(data);
});
} //end getData
getData(function (data) {
console.log(data);
});
Produces:
You could also return a promise from getData rather than passing in a callback.
您也可以从getData返回一个promise,而不是传入一个回调。
#1
4
var d1 = $.Deferred();
foo.doAsync({
success: function (d) {
data.foo = d;
d1.resolve();
}
});
var d2 = $.Deferred();
bar.doAsync({
success: function (d) {
data.bar = d;
d2.resolve();
}
});
var json_deferred = $.getJSON("/api/", function (d) {
data.user = d;
getDataDone();
});
$.when(d1, d2, json_deferred).then(function() {
alert('all requests finished');
});
Is there any benefit to using deferred over what I have?
使用延迟比我有什么好处?
Yep, deferreds allow more control on the app flow and usually (this case isn't an exception) provide more clear solutions.
是的,延迟允许更多地控制应用流程,并且通常(这种情况不是例外)提供更清晰的解决方案。
Hint: if you only need the result of asynchronous requests in the callback and nothing else - you may pass the result to the resolve
call like d1.resolve(d);
and then get it as a parameter of then()
callback, instead of using shared object as a temporary storage.
提示:如果您只需要回调中的异步请求结果而不需要其他内容 - 您可以将结果传递给解析调用,如d1.resolve(d);然后将其作为then()回调的参数,而不是使用共享对象作为临时存储。
In case of getJSON()
you could even omit the callback:
在getJSON()的情况下,您甚至可以省略回调:
var json_deferred = $.getJSON('/api/');
#2
1
Using jQuery.when: http://api.jquery.com/jQuery.when/ you can wait for several promises to finish.
使用jQuery.when:http://api.jquery.com/jQuery.when/你可以等待几个承诺完成。
You could wrap your doAsync()
methods in promises.
你可以将你的doAsync()方法包装在promises中。
function doAsync (opts) {
var msg = this.msg;
var data = { json: JSON.stringify({ msg: msg }) };
$.ajax("/echo/json/", {
type: "post",
data: data
}).then(opts.success);
}
var foo = { msg: "foo", doAsync: doAsync };
var bar = { msg: "bar", doAsync: doAsync };
function createPromise (doAsyncAble) {
var dfd = $.Deferred();
doAsyncAble.doAsync({
success: function (d) {
dfd.resolve(d);
}
});
return dfd.promise();
}
function getData(cb) {
var fooPromise = createPromise(foo);
var barPromise = createPromise(bar);
var apiPromise = $.ajax("/echo/json/", {
type: "post",
data: { json: JSON.stringify({ data: "api" }) }
});
$.when(fooPromise, barPromise, apiPromise).done(function (fooResponse, barResponse, apiResponse) {
var data = {};
data.foo = fooResponse;
data.bar = barResponse;
data.user = apiResponse[0];
cb(data);
});
} //end getData
getData(function (data) {
console.log(data);
});
Produces:
You could also return a promise from getData rather than passing in a callback.
您也可以从getData返回一个promise,而不是传入一个回调。