Chapter: 6.页面和服务器通信代码的开发
title:6.5代码优化-使用ES6+promise组织异步代码
前言
问题
之前为了实现异步执行,是通过不断使用回调函数。导致代码嵌套层次过深,显得不够优雅。
解决办法:如何更好地组织异步代码
- 事件消息通知(在Promise出现之前用得比较多)
- ES6 Promise(一种ES6支持的异步代码组织方式,jQuery等也支持)
- ES6 generator(ES6本身的特性)
本文介绍使用ES6 Promise的方法
ES6 Promise使用简介概括
1. 使用时要先创建一个对象,该对象参数是一个匿名函数,匿名函数有resolve和reject两个参数,异步操作成功执行resolve()方法,失败执行reject()方法.
2. 在异步操作返回结果时,执行then方法,then方法可分别制定resolve和reject状态的回调函数。可以有多个then方法。
实现思路
-
使用严格模式的声明
有这个方法才可以使用ES6的一些方法
-
创建对应实现
getFictionInfo
功能的promise对象getFictionInfoPromise
- 把之前写的
getFictionInfo
定义的相应代码粘贴到getFictionInfoPromise
的定义中 - 删除里面的callback
- 添加判断及
resolve()
和reject()
函数的调用
- 把之前写的
调用
getFictionInfoPromise
对象的then函数类似2,3步,创建
getCurrentChapterContentPromise
对象并调用
代码实现
-
使用严格模式的声明
在最外层闭包内的最前面加上`use strict;`
-
创建对应实现
getFictionInfo
功能的promise对象getFictionInfoPromise
var getFictionInfoPromise=function(){ return new Promise(function(resolve,reject){//在调用时创建promise对象 $.get("./data/chapter.json",function(data){ //DO:处理获得的章节信息 if(data.result==0){ chapter_id=Util.StorageGetter('last_chapter_id'); if(chapter_id==null) { chapter_id=data.chapters[1].chapter_id;//获取章节的id } chapter_total=data.chapters.length; resolve(); }else{ reject({msg:'get fiction info fail'}); } },"json");//,参数(接口,回调函数),只供演示使用,不代表真实数据接口 }); }
-
调用
getFictionInfoPromise
对象的then函数在init的调用里 注释掉原来的
getFictionInfo
函数调用,添加getFictionInfoPromise
对象的then函数调用
此时发现这样的改动仍然需要嵌套,似乎没什么区别,是因为只有一次回调的情况下,是看不出优化效果的。所以接下来要对getCurrentChapterContent
也promise化
-
类似2,3步,创建
getCurrentChapterContentPromise
对象并调用创建
getCurrentChapterContentPromise
对象var getCurrentChapterContentPromise=function(){ return new Promise(function(resolve,reject){ $.get("./data/data"+chapter_id+".json",function(data){ if(data.result==0){//判断服务器状态,不同公司不一样,有些喜欢在返回的字段价格code或result或message,都是预先设定好的,这里等于0表示是OK的 var url=data.jsonp;//由提供的数据的结构,解析出返回的数据的jsonp值,即为真实数据(base64加密)的地址。 Util.getBSONP(url,function(data){//base64解密 //debugger 回顾数据结构 //callback && callback(data); resolve(data); }); }else{ reject({msg:'get content fail'}); } },"json"); }); }
修改函数调用