我需要通过Socket.IO(客户端)通过websockets运行一系列调用。由于我没有使用$ .ajax,jQuery的延迟函数也不会集成,我将不得不手动处理promises。随着每个websocket调用,我通过回调,我很快就会看到这个项目如何失控。这是我的websocket调用如何工作的简化示例(不包括所有连接处理代码):
function js2node(nodeFunction, data, callback){
socket.emit('incoming', nodeFunction, data, callback);
}
function sampleServerCall(){
js2node('sampleCall', 'something', 'sampleCallback');
}
function sampleCallback(json){
// Handle data
}
sampleServerCall();
我将与服务器进行相当多的讨论,所有调用都将是异步的,但有些需要按特定顺序返回。输入jQuery deferred。这是一些有效的代码:
var deferredArray = [];
$(function(){
$.when( // Any order
getData1(),
getData2()
).then(function(){ // Must have responses from dataCallback1 and dataCallback2 before doing this...
$.when( // Any order
getData3(),
getData4()
).then(function(){ // Must have responses from dataCallback3 and dataCallback4 before doing this...
getData5();
});
});
});
function getData1(){
js2node('data1', 'something', 'dataCallback1');
deferredArray[0] = new $.Deferred();
return deferredArray[0].promise();
}
function getData2(){
js2node('data2', 'something', 'dataCallback2');
deferredArray[1] = new $.Deferred();
return deferredArray[1].promise();
}
function getData3(){
js2node('data3', 'something', 'dataCallback3');
deferredArray[2] = new $.Deferred();
return deferredArray[2].promise();
}
function getData4(){
js2node('data4', 'something', 'dataCallback4');
deferredArray[3] = new $.Deferred();
return deferredArray[3].promise();
}
function getData5(){
js2node('data5', 'something', 'dataCallback5');
deferredArray[4] = new $.Deferred();
return deferredArray[4].promise();
}
function dataCallback1(json){
// Handle data
deferredArray[0].resolve();
}
function dataCallback2(json){
// Handle data
deferredArray[1].resolve();
}
function dataCallback3(json){
// Handle data
deferredArray[2].resolve();
}
function dataCallback4(json){
// Handle data
deferredArray[3].resolve();
}
function dataCallback5(json){
// Handle data
deferredArray[4].resolve();
}
正如你所看到的那样,当我添加功能时,我仍然坚持使用嵌套式回调,因为我正在使用/然后嵌套可能会更深入。 Deferred对我来说是一个新概念,但我已经读过它应该在这样的情况下提供帮助。我觉得必须有比我现在做的更好的方式。任何人都可以帮我更有效地设置它吗?
答案 0 :(得分:6)
你可以用.then:
做更多事情$(function(){
$.when(
doSock('data1', 'something'),
doSock('data2', 'something')
).then(function(data1, data2){
return $.when(
doSock('data3', 'something'),
doSock('data4', 'something')
);
}).then(function(data3, data4){
return doSock('data5', 'something');
});
});
这样你的嵌套永远不会比那更深。
(我使用了adeneo的辅助方法)
答案 1 :(得分:3)
使用更好的辅助函数肯定会有所帮助,但你仍然需要使用$ .when和$ .then构建调用以正确的顺序执行它们
function doSock(nodeFunction, data) {
var def = new $.Deferred();
socket.emit('incoming', nodeFunction, data, function(received) {
def.resolve(received)
});
return def.promise();
}
$(function(){
$.when(
doSock('data1', 'something'),
doSock('data2', 'something')
).then(function(data1, data2){
$.when(
doSock('data3', 'something'),
doSock('data4', 'something')
).then(function(data3, data4){
doSock('data5', 'something');
});
});
});