通过四个异步调用收集数据到对象,并立即处理对象
Collect data to object with four async calls and handle the object onready
我有一个处理程序(回调),一个要处理的对象和四个函数,它们收集到对象的数据。在我的例子中,我希望异步调用四个数据检索器,当所有四个数据检索器的执行完成时,处理结果对象(类似于以下内容):
var data = {};
function handle (jsObj) {}
// data retrieving
function getColorData () {}
function getSizeData () {}
function getWeightData () {}
function getExtraData () {}
data.color = getColorData();
data.size = getSizeData();
data.weight = getWeightData();
data.extra = getExtraData();
handle( data );
当然,这段代码不能正常工作。如果我链接数据检索函数,它们会一个接一个被调用,对吧?这四个函数都应该异步调用,因为它们执行的时间太长,不能一个一个地调用。
更新:
感谢大家的建议!我更喜欢$.Deferred()
,但我发现让它按我需要的方式工作有点困难。我需要的是异步制作一个view
,这需要四种数据(extraData
, colorData
, sizeData
&weightData
)和我有三个对象:App
, Utils
&Tools
。
只是一个小的描述:view
是通过调用App.getStuff
作为回调传递App.handleStuff
来创建的。App.getStuff
函数体中的回调函数只调用$.when(App.getExtraData(), App.getColorData(), App.getSizeData(), App.getWeightData())
。在此之前,Utils.asyncRequest
传递Tools.parseResponse
作为回调函数。
那么,现在的问题是我是否应该在每个App.get*Data()
和return deferred.promise()
中创建四个延迟对象?我应该deferred.resolve()
在最后一个函数在我的顺序(Tools.parseResponse
为App.getExtraData
在我的例子)?
var view,
App,
Utils = {},
Tools = {};
// Utils
Utils.asyncRequest = function (path, callback) {
var data,
parseResponse = callback;
// do something with 'data'
parseResponse( data );
};
// Tools
Tools.parseResponse = function (data) {
var output = {};
// do something to make 'output' from 'data'
/* So, should the deferred.resolve() be done here? */
deferred.resolve(output);
/// OR deferred.resolve();
/// OR return output;
};
// App
App = {
// Only one method really works in my example
getExtraData : function () {
var deferred = new jQuery.Deferred();
Utils.asyncRequest("/dir/data.txt", Tools.parseResponse);
return deferred.promise();
},
// Others do nothing
getColorData : function () { /* ... */ },
getSizeData : function () { /* ... */ },
getWeightData : function () { /* ... */ }
};
App.getStuff = function (callback) {
$.when(
App.getExtraData(),
App.getColorData(),
App.getSizeData(),
App.getWeightData()
)
.then(function (extraData, colorData, sizeData, weightData) {
var context,
handleStuff = callback;
// do something to make all kinds of data become a single object
handleStuff( context );
});
};
App.handleStuff = function (stuff) { /* ... */ };
/// RUN
view = App.getStuff( App.handleStuff );
我没有期望上面示例中的代码能够工作,这是为了说明目的。
我一直试图解决这个安静的很长一段时间,它仍然没有结果。不幸的是,jQuery.Deferred()
的文档和围绕这一点的讨论并没有帮助我。因此,我将非常高兴并感谢任何帮助或建议。
从概念上讲,您将使用一个计数器,该计数器在每个异步调用完成时递增。主调用方应该在计数器被所有异步调用加完之后继续。
我想你要找的是承诺/延迟。
对于承诺,你可以这样写:
when(getColorData(), getSizeData(), getWeightData(), getExtraData()).then(
function (colorData, sizeData, weightData, extraData) {
handle(/*..*/);
}
)
当异步调用完成时,get*Data()
函数将返回一个承诺。
,
function getData() {
var promise = new Promise();
doAjax("getData", { "foo": "bar" }, function (result) {
promise.resolve(result);
});
return promise;
}
when
只是简单的计算参数的个数,如果所有的promise都被解析了,它会调用then
来计算promise的结果。
jQuery有一个OK实现:http://api.jquery.com/jQuery.when/
对于这种情况,我的建议是这样的。编写如下函数
var completed = 0;
checkHandler = function() {
if(completed == 4) {
handle(data);
}
}
,其中completed是您必须接收的正面回调数。一旦每个函数都收到回调,就可以增加"completed"计数器并调用checkHandler函数。这样就完成了!
在示例function getColorData() {
$.get('ajax/test.html', function(data) {
completed++;
checkHandler();
});
}
- 将嵌套对象数据添加到窗体中
- 使用javascript更改嵌套对象数据
- 如何将状态对象/数据传递给(异步)ajax 回调
- 如何使用HTML5中的sessionStorage概念在Javascript中打印对象数据
- 如何在express中使用socket.io发布多个对象数据
- 如何在 Javascript 中将函数绑定到对象数据成员的更改
- 在$.ajax调用中将附加数据添加到jQuery包装的对象数据中
- 当点击处理程序添加到谷歌地图圆圈标记时,无法访问对象数据
- JavaScript对象数据和数组
- 访问主数组内的数组中的对象数据
- 角度.js从NG重复更新对象数据
- HTML 对象数据文件(如果未找到)
- 设置对象数据结构数组属性
- Ajax 请求不发送我的对象数据
- 获取对象数据的浅拷贝的最快方法是什么
- 如何访问对象的键值?希望从对象数据填充表
- JSON.parse 似乎不解析对象数据
- 在 android WebView 中的 java 和 javascript 之间共享对象(数据)
- 选择 JSON 对象数据表元素以列出其所有元素
- 当响应 JSON 对象数据计数为零时,AJAX 成功回调函数重定向到错误回调