python异步回调函数的实现
来源:互联网 发布:mac怎么查看java版本 编辑:程序博客网 时间:2024/05/15 13:22
说到异步回调函数的应用,最经典的就是ajax。
首先我们回想一下ajax是如何工作的。
variable=new XMLHttpRequest();xmlhttp.onreadystatechange=function(){if (xmlhttp.readyState==4 && xmlhttp.status==200){document.getElementById("myDiv").innerHTML=xmlhttp.responseText;}}xmlhttp.open("GET","test1.txt",true);xmlhttp.send();
这是一个经典的ajax使用方式,创建对象后为对象绑定回调函数,然后发送请求到远程服务器,由于是异步,所以继续往下执行,当远程服务器返回的时候,调用绑定的回调函数。
这里我们看到浏览器为我们做了一些事情,1、发送请求到远程服务器,2、监听远程服务器的返回,并且根据返回找到了对应的回调函数,然后执行。
实际上这里可以分成3个模型,一是脚本执行流程,二是浏览器底层,三是远程服务器。
而且为了实现python的异步回调函数也需要这三个模型。
根据自己的需要,我做了3个模型。
1是监听器listener,相当于浏览器底层。
作用是:监听7800端口
负责接收来自YoSQL服务器的回复
然后解析协议,得到回调函数的ID,通知逻辑进程执行回调函数
从YoSQL服务器发来的协议格式是“[id]message”,字符串表示
2是逻辑进程main,相当于脚本执行流程
作用是:
执行逻辑
发送消息和回调函数ID到YoSQL服务器,端口3316
执行逻辑
当收到YoSQL服务器的回复的时候执行回调函数
执行逻辑
。。。。
从逻辑进程发送到YoSQL服务器的协议是“[id]message”,字符串表示
3是YoSQL服务器,相当于远程服务器
作用是:
监听3316端口
接收消息,解析协议,休眠2秒,回复监听器7800端口
YoSQL是一个独立的进程。为了简化开发,我将listener和main放到一个进程里面,分为2个线程来执行。当然你也可以用C来实现listener,C和python能够共享对象,实现起来也方便。
下面直接贴代码吧。
YoSQL代码
#-*-coding:utf-8-*-from socket import *import timedef main():HOST = ""PORT = 3316BUFSIZE = 1024ADDR = (HOST, PORT)tcpSerSock = socket(AF_INET, SOCK_STREAM)tcpSerSock.bind(ADDR)tcpSerSock.listen(5)print "YoSQL bind port %d ,starting ...." % PORTwhile 1:print 'waiting for connection ...'tcpCliSock, addr = tcpSerSock.accept()print '...connected from:',addrwhile 1:try:data = tcpCliSock.recv(BUFSIZE)if not data:breakprint 'data = %s' % datai = data.find('[')j = data.find(']')if i!=-1 and j!=-1:sFuncId = data[i+1:j]message = data[j+1:]time.sleep(2)SendToListener("[%s] echo" % sFuncId)except Exception, e:print ebreaktcpCliSock.close()tcpSerSock.close()def SendToListener(message):listenerSock = socket(AF_INET, SOCK_STREAM)listenerSock.connect(('localhost',7800))listenerSock.send(message)listenerSock.close()print 'send to listener: %s' % messageif __name__ == '__main__':main()
#-*-coding:utf-8-*-import threadingimport timefrom socket import *lCallback = {}iFuncId = 0 def StartListener():global iFuncIdglobal lCallbackHOST = ""PORT = 7800BUFSIZE = 1024ADDR = (HOST, PORT)tcpSerSock = socket(AF_INET, SOCK_STREAM)tcpSerSock.bind(ADDR)tcpSerSock.listen(5)print "Listener bind port %d ,starting ...." % PORTwhile 1:print 'waiting for connection ...'tcpCliSock, addr = tcpSerSock.accept()print '...connected from:',addrwhile 1:try:data = tcpCliSock.recv(BUFSIZE)if not data:breakprint 'data = %s' % datai = data.find('[')j = data.find(']')if i!=-1 and j!=-1:iFuncId = int(data[i+1:j])message = data[j+1:]func = lCallback.get(iFuncId,None)if func:func()del lCallback[iFuncId]except Exception,e:print ebreaktcpCliSock.close()tcpSerSock.close()def MyCallback():print 'callback called !!!!!!!!!!'def Send(callback,message):global iFuncIdglobal lCallbacklCallback[iFuncId] = callbacklistenerSock = socket(AF_INET, SOCK_STREAM)listenerSock.connect(('localhost',3316))listenerSock.send("[%d] %s" % (iFuncId,message))listenerSock.close()iFuncId += 1print 'send message to YoSQL : %s'%messagedef DoSomeThing():print '......DoSomeThing......'if __name__ == '__main__':t = threading.Thread(target=StartListener)t.setDaemon(True)t.start()# t.join()DoSomeThing()DoSomeThing()Send(MyCallback,"hahaha")i = 0while i < 20:i+= 1DoSomeThing()try:time.sleep(0.5)except Exception,e:print ebreak# t.join(2)print '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>'
下面是执行结果图:
可以看到发送信息到远程服务器之后主逻辑继续往下执行,并没有阻塞,当远程服务器返回的时候回调函数被执行了
- python异步回调函数的实现
- 通过回调函数实现异步
- python的回调函数
- python 回调函数和回调方法的实现
- python 回调函数和回调方法的实现
- 回调函数 异步执行
- 什么是回调函数?回调函数的简单实现。
- javascript 实现多个异步函数的同时执行后再执行回调函数
- PYTHON 回调函数
- Python 回调函数
- PYTHON 回调函数
- python--回调函数
- python 回调函数
- python回调函数的使用方法
- 异步委托调用和回调函数的结合使用
- 异步消息的传递—回调函数
- 如何按照顺序执行异步ajax的回调函数
- Node.js 异步非阻塞的回调函数
- 文件内容搜索
- Ubuntu 10.04 下载android4.2 源码
- Binary String Matching
- 孤立词语音识别系统
- LTE之载波聚合(一):简介
- python异步回调函数的实现
- Uva 10392
- hdu2524矩形A + B
- java.util包
- ubuntu下新增一个用户以及拥有sudo权限方法
- 谁做的好事
- struts-config.xml中action、forward、form-bean属性含义
- 一种排序
- Ubuntu 10.04 下载android4.2 源码