Promise相关
来源:互联网 发布:java两个日期相差年数 编辑:程序博客网 时间:2024/06/16 16:14
参考:http://www.jianshu.com/p/fe5f173276bd
一、 Promise对象有三种状态,他们分别是:
- pending: 进行中,表示还没有得到结果
- resolved(Fulfilled): 已完成,表示得到了我们想要的结果,可以继续往下执行
- rejected: 已失败,也表示得到结果,但是由于结果并非我们所愿,因此拒绝执行
这三种状态不受外界影响,而且状态只能从pending改变为resolved或者rejected,并且不可逆。在Promise对象的构造函数中,将一个函数作为第一个参数。而这个函数,就是用来处理Promise的状态变化。
new Promise(function (resolve,reject) { if(true){ resolve() }; if(false){ reject() }; });
二、 Promise对象中的then方法,可以接收构造函数中处理的状态变化,并分别对应执行。then方法有2个参数,第一个函数接收resolved状态的执行,第二个参数接收reject状态的执行。其中,第二个函数是可选的,不一定提供。这两个函数都接受Promise对象传出的值作为参数。function fn(num) { return new Promise(function (resolve,reject) { if(typeof num=="number"){ resolve(); }else{ reject(); } }).then(function () { console.log("参数是number值"); },function(){ console.log("参数不是number值"); });}fn(123);fn("abc");then方法的执行结果也会返回一个Promise对象。因此我们可以进行then的链式执行,这也是解决回调地狱的主要方式。
function fn(num) { return new Promise(function (resolve,reject) { if(typeof num=="number"){ resolve(); }else{ reject(); } }).then(function () { console.log("参数是number值"); }).then(null,function(){ console.log("参数不是number值"); });}fn(123);fn("abc");then(null, function() {}) 等同于catch(function() {}),将第一个参数:已完成调用的函数引用置为null。
三、Promise中的数据传递
如下所示:
function fn(num) { return new Promise(function (resolve,reject) { if(typeof num=="number"){ resolve(num); }else{ reject("TypeError"); } });}fn(1).then(function (num) { console.log('first: ' +num); return num+1;}).then(function (num) { console.log('second: ' +num); return num+1;}).then(function (num) { console.log('third: ' +num); return num+1;});
OK,了解了这些基础知识之后,我们再回过头,利用Promise的知识,对最开始的ajax的例子进行一个简单的封装。看看会是什么样子。
var url="http://www.XXX.com/posts.json";function getJSON(url) { return new Promise(function (resolve, reject) { var xhr = new XMLHttpRequest(); xhr.open("get", url, true); xhr.onreadyStateChange=handler; xhr.responseType="json"; xhr.setRequestHeader("Accept","application/json"); xhr.send(); function handler() { if (this.readyState != "4") { return; } if (this.status == "200") { try{ resolve(this.response); }catch(e){ reject(e); } } else { reject(new Error(this.statusText)); } } });};getJSON(url).then(function (json) { console.log("contents:"+json);},function (error) { console.log("出错了",error);});
为了健壮性,处理了很多可能出现的异常,总之,就是正确的返回结果,就resolve一下,错误的返回结果,就reject一下。并且利用上面的参数传递的方式,将正确结果或者错误信息通过他们的参数传递出来。
PS:现在所有的库几乎都将ajax请求利用Promise进行了封装,因此我们在使用jQuery等库中的ajax请求时,都可以利用Promise来让我们的代码更加优雅和简单。这也是Promise最常用的一个场景,因此我们一定要非常非常熟悉它,这样才能在应用的时候更加灵活。
四、Promise.all
当有一个ajax请求,它的参数需要另外2个甚至更多请求都有返回结果之后才能确定,那么这个时候,就需要用到Promise.all来帮助我们应对这个场景。
Promise.all接收一个Promise对象组成的数组作为参数,当这个数组所有的Promise对象状态都变成resolved或者rejected的时候,它才会去调用then方法。
var promises=[2,3,5,7,11,13].map(function (id) { return getJSON("/post/"+id+".json");});Promise.all(promises).then(function (posts) { //...}).catch(function (reason) { //...});
注意:map函数对数组中每一项运行给定函数,返回每次函数调用的结果组成的数组。
五、 Promise.race
与Promise.all相似的是,Promise.race都是以一个Promise对象组成的数组作为参数,不同的是,只要当数组中的其中一个Promsie状态变成resolved或者rejected时,就可以调用.then方法了。而传递给then方法的值也会有所不同,大家可以再浏览器中运行下面的例子与上面的例子进行对比。
var p=Promise.race([getJSON(url),getJSON(url1)]);p.then(function (value) { console.log(value);});
- Promise相关
- ES6中的Promise相关知识简述
- promise
- Promise
- Promise
- Promise
- Promise
- Promise
- Promise
- promise
- promise
- promise
- promise
- Promise
- Promise
- promise
- promise
- Promise
- 在没有串口的情况下,调整打log的优先级的方法
- LeetCode 459. Repeated Substring Pattern
- 5.13
- [leetcode: Python]242.Valid Anagram
- jvm 垃圾收集器
- Promise相关
- POJ 2187 旋转卡壳 解题报告
- 点击小图弹出大图片且手势放大和缩放功能
- const用法
- easyui-datebox前一个选择了日期,后一个只能该日期之后的日期,或是一个周之后的日期
- ZCMU—1556
- Spring MVC中加载配置properties文件(以配置Redis为例)
- 数据结构草稿
- 信号同步