js websocket同步等待_异步与websocket

异步与WebSockets

知识点

理解同步与异步执行过程

理解异步代码的回调写法与yield写法

Tornado异步

异步Web客户端AsyncHTTPClient

tornado.web.asynchronous

tornado.gen.coroutine

并行协程用法

WebSocket的使用

认识异步

1. 同步

我们用两个函数来模拟两个客户端请求,并依次进行处理:

#coding:utf-8

defreq_a():"""模拟请求a"""

print '开始处理请求req_a'

print '完成处理请求req_a'

defreq_b():"""模拟请求b"""

print '开始处理请求req_b'

print '完成处理请求req_b'

defmain():"""模拟tornado框架,处理两个请求"""req_a()

req_b()if __name__ == "__main__":

main()

执行结果:

开始处理请求req_a

完成处理请求req_a

开始处理请求req_b

完成处理请求req_b

同步是按部就班的依次执行,始终按照同一个步调执行,上一个步骤未执行完不会执行下一步。

想一想,如果在处理请求req_a时需要执行一个耗时的工作(如IO),其执行过程如何?

#coding:utf-8

importtimedeflong_io():"""模拟耗时IO操作"""

print "开始执行IO操作"time.sleep(5)print "完成IO操作"

return "io result"

defreq_a():print "开始处理请求req_a"ret=long_io()print "ret: %s" %retprint "完成处理请求req_a"

defreq_b():print "开始处理请求req_b"

print "完成处理请求req_b"

defmain():

req_a()

req_b()if __name__=="__main__":

main()

执行过程:

开始处理请求req_a

开始执行IO操作

完成IO操作

完成处理请求req_a

开始处理请求req_b

完成处理请求req_b

在上面的测试中,我们看到耗时的操作会将代码执行阻塞住,即req_a未处理完req_b是无法执行的。

我们怎么解决耗时操作阻塞代码执行?

2. 异步

对于耗时的过程,我们将其交给别人(如其另外一个线程)去执行,而我们继续往下处理,当别人执行完耗时操作后再将结果反馈给我们,这就是我们所说的异步。

我们用容易理解的线程机制来实现异步。

2.1 回调写法实现原理

#coding:utf-8

importtimeimportthreaddeflong_io(callback):"""将耗时的操作交给另一线程来处理"""

def fun(cb): #回调函数作为参数

"""耗时操作"""

print "开始执行IO操作"time.sleep(5)print "完成IO操作,并执行回调函数"cb("io result") #执行回调函数

thread.start_new_thread(fun, (callback,)) #开启线程执行耗时操作

defon_finish(ret):"""回调函数"""

print "开始执行回调函数on_finish"

print "ret: %s" %retprint "完成执行回调函数on_finish"

defreq_a():print "开始处理请求req_a"long_io(on_finish)print "离开处理请求req_a"

defreq_b():print "开始处理请求req_b"time.sleep(2) #添加此句来突出显示程序执行的过程

print "完成处理请求req_b"

defmain():

req_a()

req_b()while 1: #添加此句防止程序退出,保证线程可以执行完

pass

if __name__ == '__main__':

main()

执行过程:

开始处理请求req_a

离开处理请求req_a

开始处理请求req_b

开始执行IO操作

完成处理请求req_b

完成IO操作,并执行回调函数

开始执行回调函数on_finish

ret: io result

完成执行回调函数on_finish

异步的特点是程序存在多个步调,即本属于同一个过程的代码可能在不同的步调上同时执行。

2.2 协程写法实现原理

在使用回调函数写异步程序时,需将本属于一个执行逻辑(处理请求a)的代码拆分成两个函数req_a和on_finish,这与同步程序的写法相差很大。而同步程序更便于理解业务逻辑,所以我们能否用同步代码的写法来编写异步程序?

回想yield关键字的作用?

初始版本

#coding:utf-8

importtimeimportthread

gen= None #全局生成器,供long_io使用

deflong_io():deffun():print "开始执行IO操作"

globalgen

time.sleep(5

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值