Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选

首页 / 脚本样式 / JavaScript / javascript Promise简单学习使用方法小结

解决回调函数嵌套太深,并行逻辑必须串行执行,一个Promise代表一个异步操作的最终结果,跟Promise交互的主要方式是通过他的then()方法来注册回调函数,去接收Promise的最终结果值
Promise相关的协议有PromiseA和PromiseA+
定义一个类Promise
定义属性队列queue,初始化空数组[]
定义属性值value,初始化null
定义属性状态status,初始化“pending”(默认值)
定义成员方法getQueue(),返回属性queue
定义成员方法getStatus(),返回属性status
定义成员方法setStatus(),设置状态,传递参数:status,value
判断status为fulfilled或者rejected,
设置status属性this.status=status
设置value属性this.value=value || null ,如果不传value就是null

定义冻结变量freezeObject
定义成员方法isFulfilled(),判断当前状态是否是(完成)
定义成员方法isRejected(),判断当前状态是否是(失败)
定义成员方法isPending(),判断当前状态师傅是(等待)
定义成员方法then(),传递参数:onFulfilled成功的回调,onRejected失败的回调
定义对象handler对象,属性fulfilled,rejected两个回调函数
定义handler对象的deferred属性,Deferred对象
判断当前状态是否等待,如果是等待 把handler对象塞入queue队列数组
如果不是等待状态,调用Utils对象的procedure()方法,参数:status,
返回 handler.deferred.promise对象

定义一个类Deferred
定义属性promise,初始化Promise对象
定义成员方法resolve(),传递参数:result结果
判断Promise对象的状态是 等待,直接返回
调用Promise对象的getQueue()方法,获取queue数组
循环数组
//todo调用工具类Utils. procedure()方法,参数:“fulfilled”,元素,err信息
调用Promise对象的setStatus()方法,设置状态,参数:"fulfilled",result

定义成员方法reject,传递参数:err错误信息
判断Promise对象的状态是 等待,直接返回
调用Promise对象的getQueue()方法,获取queue数组
循环数组
//todo,调用工具类Utils. procedure()方法,参数:“rejected”,元素,err信息
调用Promise对象的setStatus()方法,设置状态,参数:"fulfilled",result

定义工具类Utils,使用匿名函数立即执行,得到一个对象
 
返回对象,对象中有一个方法procedure()
定义procedure()方法,传递参数:type状态类型,handler处理器数组,result结果
获取到处理函数func,在handler[type]
到这里我看晕了。。。
 
使用方法:
定义一个函数ajax,传递参数:url路径
 
获取Deferred对象,new出来
ajax请求数据的代码,在返回数据的回调方法中
如果成功了调用Deferred对象的resolve()方法,参数:返回的数据
如果失败了调用Deferred对象的reject()方法,参数:返回的数据
返回Deferred.promise对象

调用ajax()方法,得到promise对象,参数:url,
调用promise对象的then()方法,参数:匿名函数
调用ajax()方法,获取到promise对象,返回这个对象
形成链式调用
 
js部分:
<script>//Promise代码部分(我选择狗带)Promise = function() {this.queue = [];this.value = null;this.status = "pending";// pending fulfilled rejected};Promise.prototype.getQueue = function() {return this.queue;};Promise.prototype.getStatus = function() {return this.status;};Promise.prototype.setStatus = function(s, value) {if (s === "fulfilled" || s === "rejected") {this.status = s;this.value = value || null;this.queue = [];var freezeObject = Object.freeze || function(){};freezeObject(this);// promise的状态是不可逆的} else {throw new Error({message: "doesn"t support status: " + s});}};Promise.prototype.isFulfilled = function() {return this.status === "fulfilled";};Promise.prototype.isRejected = function() {return this.status === "rejected";}Promise.prototype.isPending = function() {return this.status === "pending";}Promise.prototype.then = function(onFulfilled, onRejected) {var handler = {"fulfilled": onFulfilled,"rejected": onRejected};handler.deferred = new Deferred();if (!this.isPending()) {//这里允许先改变promise状态后添加回调utils.procedure(this.status, handler, this.value);} else {this.queue.push(handler);//then may be called multiple times on the same promise;规范2.2.6}return handler.deferred.promise;//then must return a promise;规范2.2.7};var utils = (function(){var makeSignaler = function(deferred, type) {return function(result) {transition(deferred, type, result);}};var procedure = function(type, handler, result) {var func = handler[type];var def = handler.deferred;if (func) {try {var newResult = func(result);if (newResult && typeof newResult.then === "function") {//thenable// 此种写法存在闭包容易造成内存泄露,我们通过高阶函数解决// newResult.then(function(data) {// def.resolve(data);// }, function(err) {// def.reject(err);// });//PromiseA+规范,x代表newResult,promise代表def.promise//If x is a promise, adopt its state [3.4]://If x is pending, promise must remain pending until x is fulfilled or rejected.//If/when x is fulfilled, fulfill promise with the same value.//If/when x is rejected, reject promise with the same reason.newResult.then(makeSignaler(def, "fulfilled"), makeSignaler(def, "rejected"));//此处的本质是利用了异步闭包} else {transition(def, type, newResult);}} catch(err) {transition(def, "rejected", err);}} else {transition(def, type, result);}};var transition = function(deferred, type, result) {if (type === "fulfilled") {deferred.resolve(result);} else if (type === "rejected") {deferred.reject(result);} else if (type !== "pending") {throw new Error({"message": "doesn"t support type: " + type});}};return {"procedure": procedure}})();Deferred = function() {this.promise = new Promise();};Deferred.prototype.resolve = function(result) {if (!this.promise.isPending()) {return;}var queue = this.promise.getQueue();for (var i = 0, len = queue.length; i < len; i++) {utils.procedure("fulfilled", queue[i], result);}this.promise.setStatus("fulfilled", result);};Deferred.prototype.reject = function(err) {if (!this.promise.isPending()) {return;}var queue = this.promise.getQueue();for (var i = 0, len = queue.length; i < len; i++) {utils.procedure("rejected", queue[i], err);}this.promise.setStatus("rejected", err);}/*****************************上面看不懂,分割线************************************///测试部分ajax = function(url) {var def = new Deferred();var xhr = new XMLHttpRequest();xhr.onreadystatechange = function() {if (xhr.readyState === 4) {if ((xhr.status >=200 && xhr.status < 300) || xhr.status === 304) {def.resolve(xhr.responseText)} else {//简化ajax,没有提供错误回调def.reject(new Error({message: xhr.status}));}}};xhr.open("get", url, true);xhr.send(null);return def.promise;}ajax("test.php?act=1").then(function(data1) {console.log(data1);//处理data1return ajax("test.php?act=2");}).then(function(data2) {console.log(data2);//处理data2return ajax("test.php?act=3");}, function(err) {console.error(err);}).then(function(data3) {console.log(data3);alert("success");}, function(err) {console.error(err);});</script>
php:
<?phpif($_GET["act"]==1){echo json_encode(array("code"=>200));}else if($_GET["act"]==2){echo json_encode(array("code"=>300));}else if($_GET["act"]==3){echo json_encode(array("code"=>400));}

以上这篇javascript Promise简单学习使用方法小结就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持脚本之家。