javascript Promise简单学习使用方法小结

前端之家收集整理的这篇文章主要介绍了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部分:

//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,result) {
var func = handler[type];
var def = handler.deferred;

if (func) {
  try {
    var newResult = func(result);
    if (newResult && typeof newResult.then === 'function') {//thenable
      // 此种写法存在闭包容易造成内存泄露,我们通过高阶<a href="https://www.jb51.cc/tag/hanshu/" target="_blank" class="keywords">函数</a><a href="https://www.jb51.cc/tag/jiejue/" target="_blank" class="keywords">解决</a>
      // 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,newResult);
    }
  } catch(err) {
    transition(def,'rejected',err);
  }
} else {
  transition(def,result);
}

};

var transition = function(deferred,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',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);//处理data1
return ajax('test.PHP?act=2');
}).then(function(data2) {
console.log(data2);//处理data2
return ajax('test.PHP?act=3');
},function(err) {
console.error(err);
}).then(function(data3) {
console.log(data3);
alert('success');
},function(err) {
console.error(err);
});

PHP

PHP;"> 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简单学习使用方法小结就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持编程之家。

原文链接:https://www.f2er.com/js/48712.html

猜你在找的JavaScript相关文章