异步编程:异步编程处理方式,主要用于数据业务的底层非同步操作,有两种操作手段,Ajax和后端服务器的异步模块。
1.Ajax
Ajax的异步操作:通过前端直接发送Ajax请求到目标服务器(以获取天气信息为例,发送请求到气象局),获取数据并更新前端页面,此操作不需要经过后端。获取到数据后通过DOM操作渲染页面。
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>ajax请求获取天气预报信息</title> <script src="static/jquery/jquery-2.2.4.js"></script> </head> <body> <form> <input type="text" name="city" id="city"><br/> <div id="info"></div> </form> <script> //失焦事件 $('#city').blur(function(){ $.ajax({ 'url':'http://wthrcdn.etouch.cn/weather_mini', type:'get', data:{city:$('#city').val()}, success:function(data){ var $_weather=JSON.parse(data); console.log($_weather); //城市 $today1=$_weather.data.city; $1 = $('<p>').text('城市:'+$today1); $hr=$('<hr>') //今日日期 $today2=$_weather.data.forecast[0].date; $2 = $('<p>').text('日期:'+$today2); //今日最高温度; $today3=$_weather.data.forecast[0].high; $3 = $('<p>').text('最高温度:'+$today3); //今日最低温度 $today4=$_weather.data.forecast[0].low; $4 = $('<p>').text('最低温度:'+$today4); //今日风向 $today5=$_weather.data.forecast[0].fengxiang; $5 = $('<p>').text('风向:'+$today5); //今日风力 $today6=$_weather.data.forecast[0].fengli; $6 = $('<p>').text('风力:'+$today6); $('#info').append($1).append($hr).append($2).append($3).append($4).append($5).append($6) }, }) }) </script> </body> </html>
2.python后端程序中的数据交互方式,又分为两种(后端同步操作和后端异步操作)。
后端同步操作:
即同步交互,核心处理类是用了tornado内置的客户端对象tornado.httpclient.HTTPClient
后端异步操作:
即异步交互,核心处理类是用了tornado内置的客户端对象的异步操作对象tornado.httpclient.AsyncHTTPClient
后端同步操作和后端异步操作的特点:
同步操作表示每次只能向目标服务器发送一个请求,待其返回数据后才能进行下一次请求,若请求较多的情况下易发生阻塞。异步操作可同时发送多个请求到目标服务器,较早返回数据的将会被优先处理。
①后端同步操作
py文件
''' 后端同步操作,服务器通过内置的客户端对象,抓取目标url地址的数据,返回给前端页面,通过dom操作渲染页面 ''' # 引入需要的模块 from tornado.web import Application, RequestHandler from tornado.ioloop import IOLoop from tornado.httpserver import HTTPServer from tornado.httpclient import HTTPClient # 定义首页视图类 class IndexHandler(RequestHandler): def get(self): self.render('index.html') # 定义获取天气的视图类 class WeatherHandler(RequestHandler): def get(self): # 获取内置的客户端对象 client = HTTPClient() # 获取要查询的城市 city = self.get_argument('city') # 抓取气象局天气预报数据,得到响应对象 response = client.fetch('http://wthrcdn.etouch.cn/weather_mini?city=' + city) # 数据被封装在响应对象的body属性中 # 将数据写入到页面中 self.write(response.body) # 定义程序运行的入口 if __name__ == '__main__': import os BASE_DIR = os.path.dirname(__file__) app = Application([ (r'/', IndexHandler), (r'/weather', WeatherHandler) ], template_path=os.path.join(BASE_DIR, 'templates'), static_path=os.path.join(BASE_DIR, 'static'), debug=True) server = HTTPServer(app) server.listen(8000) IOLoop.current().start()index.html文件
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>后端同步/异步获取数据</title> <script src="/static/jquery/jquery-2.2.4.js"></script> </head> <body> <form> 当前城市:<input type="text" name="city" id="city"> <div id="info"></div> </form> <script> $('#city').blur(function(){ //获取到输入的城市 $city=$('#city').val() //发送ajax请求到后端 $.ajax({ url:'/weather', type:'get', data:{'city':$city}, success:function(data){ $data=JSON.parse(data) console.log($data) //当前城市名称 $cty=$('<p>').text('当前城市:'+$data.data.city) $hr=$('<hr>') //今天的日期 $date=$('<p>').text('当前日期:'+$data.data.forecast[0].date) //最高气温 $high=$('<p>').text('最高气温:'+$data.data.forecast[0].high) //最低气温 $low=$('<p>').text('最低气温:'+$data.data.forecast[0].low) //风向 $fx=$('<p>').text('风向:'+$data.data.forecast[0].fengixang) //风力 $fl=$('<p>').text('风力:'+$data.data.forecast[0].fengli) //将天气信息写入到页面中 //empty()表示每次写入前先清空以前的数据 $('#info').empty().append($cty).append($hr).append($date).append($high).append($low).append($fx).append($fl) } }) }) </script> </body> </html>②后端异步操作,index.html文件与上面相同,下面是py文件
''' 后端异步操作通过异步操作对象,手动控制数据返回,实现异步获取数据 ''' # 引入需要的模块,asynchronous是一个装饰器,用来告知函数不要自动返回数据 from tornado.web import Application, RequestHandler, asynchronous from tornado.ioloop import IOLoop from tornado.httpserver import HTTPServer # 引入异步操作对象 from tornado.httpclient import AsyncHTTPClient # 定义首页视图处理类 class IndexHandler(RequestHandler): def get(self): self.render('index.html') # 定义后端异步获取天气信息的视图处理类 class WeatherHandler(RequestHandler): @asynchronous def get(self): # 获取前端输入的城市信息 city = self.get_argument('city') # 获取异步操作对象 client = AsyncHTTPClient() # 获取天气信息 client.fetch('http://wthrcdn.etouch.cn/weather_mini?city=' + city, callback=self.deal_resonse) def deal_resonse(self, response): content = response.body # 将数据返回到页面中 self.write(content) # 手动控制数据返回,finish表示可以返回数据了 self.finish() # 定义程序运行入口 if __name__=='__main__': import os BASE_DIR=os.path.dirname(__file__) app = Application([ (r'/',IndexHandler), (r'/weather',WeatherHandler) ], template_path=os.path.join(BASE_DIR,'templates'), static_path=os.path.join(BASE_DIR,'static'), debug=True) server = HTTPServer(app) server.listen(8000) IOLoop.current().start()