我试图在循环的上下文中使用deferred和promises,但我没有这样做。
我需要异步调用第一个方法。第一种方法(让我们称之为getArray())返回一个数组。
对于数组的每个元素,我需要调用第二个方法,让我们称之为getData(id)。 id存储在getArray返回的数组中。
最后,一旦我得到getData()的结果,我需要使用结果来调用第三个方法,让我们称之为getDetails()。
完成所有调用并完成循环后,我需要返回数组,并提供额外的数据和详细信息。
我创建了一个jsfiddle: http://jsfiddle.net/chevdor/953sLkts/
var myarray = [];
var log = function(s){
$('#console').append('<p>'+s+'</p>');
};
var get1 = function() {
var dfd = jQuery.Deferred();
log('Running get1');
setTimeout(function() {
var res = [1, 2, 3, 4];
// that´s probably crap...
for (var i= 0; i< res.length; i++){
get2(res[i])
.done(get3(res[i])
.done(get4(res[i]))
);
}
dfd.resolve(res);
}, Math.floor(400 + Math.random() * 1000));
return dfd.promise();
};
var get2 = function(index) {
var dfd = jQuery.Deferred();
log('Running get2');
setTimeout(function() {
var res = {
index: index,
val: index * 2
};
myarray[index]= res;
dfd.resolve(res);
}, Math.floor(400 + Math.random() * 1000));
return dfd.promise();
};
var get3 = function(index) {
var dfd = jQuery.Deferred();
log('Running get3');
setTimeout(function() {
var res = {
index: index,
val2: index * index
};
myarray[index].extra = res;
dfd.resolve(res);
}, Math.floor(400 + Math.random() * 1000));
return dfd.promise();
};
var get4 = function(index) {
var dfd = jQuery.Deferred();
log('Running get4');
setTimeout(function() { // Resolve after a random interval
var res = {
index: index,
val2: index * index
};
dfd.resolve(res);
}, Math.floor(400 + Math.random() * 1000));
return dfd.promise();
};
log('start');
get1();
来说明。它肯定不起作用,看起来很难看......
你能解释一下这样做的正确方法吗?
答案 0 :(得分:1)
我可以向您介绍$ .when。
从你的代码看,你的get2(),get3(),get4()看起来像是getData(),getDetail()。假设他们都像承诺一样。然后你可以这样做:
import wx
import socket
import threading
import sys
class oranges(wx.Frame):
def __init__(self,parent,id):
##Unimportant stuff
wx.Frame.__init__(self,parent,id," Retro Message",size=(500,500))
self.frame=wx.Panel(self)
self.input_box=wx.TextCtrl(self.frame, -1,pos=(15,350),size=(455,120),style=wx.NO_BORDER| wx.TE_MULTILINE)
self.messaging_box=wx.TextCtrl(self.frame, -1,pos=(15,15),size=(455,285),style=wx.NO_BORDER | wx.TE_MULTILINE|wx.TE_READONLY)
send_button=wx.Button(self.frame,label="Send",pos=(350,315),size=(75,40))
self.Bind(wx.EVT_BUTTON, self.sender,send_button)
self.Bind(wx.EVT_CLOSE, self.close_window)
self.counter = 1
self.socket_connect = socket.socket()
self.setup()
def sender(self,event):
self.socket_connect.send(self.input_box.GetValue())
self.input_box.Clear()
self.Refresh()
##Important stuff
def close_window(self,event): #This is the function in question#
self.counter = 0
self.socket_connect.shutdown(socket.SHUT_RDWR)
sys.exit(0)
def setup(self):
self.ip_enter = wx.TextEntryDialog(None, "Enter in the IP:", "Setup", "192.168.1.1")
if self.ip_enter.ShowModal() ==wx.ID_OK:
self.offical_ip = self.ip_enter.GetValue()
try:
self.socket_connect.connect((self.offical_ip,5003))
self.username = "false" #Tells the server just to give the user a IP username
self.Thread1 = threading.Thread(target = self.listening_connect)
self.Thread1.start()
except socket.error:
self.error_connect()
else:
sys.exit(0)
def listening_connect(self):
self.socket_connect.send(self.username)
while self.counter != 0:
data = self.socket_connect.recv(1024)
self.messaging_box.AppendText(data)
self.Refresh()
if not data:
break
self.socket_connect.close()
def error_connect(self):
pop_ups = wx.MessageDialog(None, "Failed to Connect to Server!", 'Error', wx.OK)
pop_ups.ShowModal()
self.setup()
if __name__=="__main__":
app=wx.App(False)
window=oranges(parent=None,id=-1)
window.Show()
app.MainLoop()
我是蓝鸟承诺的忠实粉丝,关键字是.all()而不是.when()。我不确定jquery承诺如何工作,但我相信它是一个非常相似的结构。希望这可以帮助。如果不清楚,请告诉我:)。
编辑:很抱歉混淆,在promises数组上使用$ .when,语法为:
import socket
HOST = '192.168.1.1'
PORT=5003
s = socket.socket()
s.bind((HOST, PORT))
s.listen(1)
c,addr = s.accept()
while True:
data = c.recv(1024)
if not data:
break
c.close()
注意这里的“数据”只是从promise1解析的,我不熟悉jquery。但我确实建议bluebird承诺。哪个更快更干净。
答案 1 :(得分:0)
尝试创建p
,.push()
到[{1}}的结果数组$.when(get2(res[i]), get3(res[i]), get4(res[i]))
,p
;通过$.when.apply
调用p
作为传递的jQuery承诺对象的数组;检查dfd.resolve(res)
的{{1}},myarray
.then
onFulfilled
处理程序的结果get1
var myarray = [];
var log = function(s){
$('#console').append('<p>'+s+'</p>');
};
var get1 = function() {
var dfd = jQuery.Deferred();
log('Running get1');
var p = [];
setTimeout(function() {
var res = [1, 2, 3, 4];
// that´s probably crap...
for (var i= 0; i< res.length; i++){
p.push($.when(get2(res[i]), get3(res[i])
, get4(res[i])))
};
$.when.apply($, p).then(function() {
dfd.resolve($.makeArray(arguments))
})
}, Math.floor(400 + Math.random() * 1000));
return dfd.promise();
};
var get2 = function(index) {
var dfd = jQuery.Deferred();
log('Running get2');
setTimeout(function() {
var res = {
index: index,
val: index * 2
};
myarray[index]= res;
dfd.resolve(res);
}, Math.floor(400 + Math.random() * 1000));
return dfd.promise();
};
var get3 = function(index) {
var dfd = jQuery.Deferred();
log('Running get3');
setTimeout(function() {
var res = {
index: index,
val2: index * index
};
myarray[index] = {"extra":res};
dfd.resolve(res);
}, Math.floor(400 + Math.random() * 1000));
return dfd.promise();
};
var get4 = function(index) {
var dfd = jQuery.Deferred();
log('Running get4');
setTimeout(function() { // Resolve after a random interval
var res = {
index: index,
val2: index * index
};
dfd.resolve(res);
}, Math.floor(400 + Math.random() * 1000));
return dfd.promise();
};
log('start');
get1().then(function() {
console.log("res:", arguments, "myarray:", myarray);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
<h1>Test</h1>
<span id='console'></span>
jsfiddle http://jsfiddle.net/953sLkts/9/