promise含义:

所谓Promise,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。

从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。

promise基本用法:

Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resolvereject。它们是两个函数,由 JavaScript 引擎提供,不用自己部署。

resolve函数的作用是,将Promise对象的状态从“未完成”变为“成功”(即从 pending 变为 resolved),在异步操作成功时调用,并将异步操作的结果,作为参数传递出去;

reject函数的作用是,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。

Promise实例生成以后,可以用then方法分别指定resolved状态和rejected状态的回调函数。

const promise = new Promise(function(resolve, reject) {
// ... some code if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
}); promise.then(function(value) {
// success
}, function(error) {
// failure
});

promise新建后就会立即执行

var promise = new Promise(function(resolve, reject) {
console.log('Promise instance');
resolve();
}); promise.then(function() {
 console.log('resolved result');
});
for(var i=0;i<100;i++) {
  console.log(i);
}
/*
Promise instance
1
2
3
...
99
100
resolved result
*/

resolve函数的参数除了正常的值以外,还可能是另一个 Promise 实例,比如像下面这样。

const p1 = new Promise(function (resolve, reject) {
// ...
}); const p2 = new Promise(function (resolve, reject) {
// ...
resolve(p1);
})

上面代码中,p1p2都是 Promise 的实例,但是p2resolve方法将p1作为参数,即一个异步操作的结果是返回另一个异步操作。

注意,这时p1的状态就会传递给p2,也就是说,p1的状态决定了p2的状态。如果p1的状态是pending,那么p2的回调函数就会等待p1的状态改变;如果p1的状态已经是resolved或者rejected,那么p2的回调函数将会立刻执行。

promise.prototype,then()

Promise 实例具有then方法,也就是说,then方法是定义在原型对象Promise.prototype上的。它的作用是为 Promise 实例添加状态改变时的回调函数。

前面说过,then方法的第一个参数是resolved状态的回调函数,第二个参数(可选)是rejected状态的回调函数。

then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。

getJSON("/posts.json").then(function(json) {
return json.post;
}).then(function(post) {
// ...
});

上面的代码使用then方法,依次指定了两个回调函数。第一个回调函数完成以后,会将返回结果作为参数,传入第二个回调函数。

采用链式的then,可以指定一组按照次序调用的回调函数。这时,前一个回调函数,有可能返回的还是一个Promise对象(即有异步操作),这时后一个回调函数,就会等待该Promise对象的状态发生变化,才会被调用。

getJSON("/post/1.json").then(function(post) {
return getJSON(post.commentURL);
}).then(function (comments) {
console.log("resolved: ", comments);
}, function (err){
console.log("rejected: ", err);
});

上面代码中,第一个then方法指定的回调函数,返回的是另一个Promise对象。这时,第二个then方法指定的回调函数,就会等待这个新的Promise对象状态发生变化。如果变为resolved,就调用第一个回调函数,如果状态变为rejected,就调用第二个回调函数。

如果采用箭头函数,上面的代码可以写得更简洁。
getJSON("/post/1.json").then(
post => getJSON(post.commentURL)
).then(
comments => console.log("resolved: ", comments),
err => console.log("rejected: ", err)
);

promise.prototype.catch()

getJSON('/posts.json').then(function(posts) {
// ...
}).catch(function(error) {
// 处理 getJSON 和 前一个回调函数运行时发生的错误
console.log('发生错误!', error);
});

上面代码中,getJSON方法返回一个 Promise 对象,如果该对象状态变为resolved,则会调用then方法指定的回调函数;

如果异步操作抛出错误,状态就会变为rejected,就会调用catch方法指定的回调函数,处理这个错误。另外,then方法指定的回调函数,如果运行中抛出错误,也会被catch方法捕获。

p.then((val) => console.log('fulfilled:', val))
.catch((err) => console.log('rejected', err)); // 等同于
p.then((val) => console.log('fulfilled:', val))
.then(null, (err) => console.log("rejected:", err));

一般来说,不要在then方法里面定义 Reject 状态的回调函数(即then的第二个参数),总是使用catch方法。

// bad
promise
.then(function(data) {
// success
}, function(err) {
// error
}); // good
promise
.then(function(data) { //cb
// success
})
.catch(function(err) {
// error
});

上面代码中,第二种写法要好于第一种写法,理由是第二种写法可以捕获前面then方法执行中的错误,也更接近同步的写法(try/catch)。因此,建议总是使用catch方法,而不使用then方法的第二个参数。

promise.protype.finally

finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。

promise
.then(result => {···})
.catch(error => {···})
.finally(() => {···});

promise.all

Promise.all方法用于将多个 Promise 实例,包装成一个新的 Promise 实例。

const p = Promise.all([p1, p2, p3]);

上面代码中,Promise.all方法接受一个数组作为参数,p1p2p3都是 Promise 实例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。(Promise.all方法的参数可以不是数组,但必须具有 Iterator 接口,且返回的每个成员都是 Promise 实例。)

p的状态由p1p2p3决定,分成两种情况。

(1)只有p1p2p3的状态都变成fulfilledp的状态才会变成fulfilled,此时p1p2p3的返回值组成一个数组,传递给p的回调函数。

(2)只要p1p2p3之中有一个被rejectedp的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。

promise.race()

Promise.race方法同样是将多个 Promise 实例,包装成一个新的 Promise 实例。

const p = Promise.race([p1, p2, p3]);

上面代码中,只要p1p2p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。

Promise.race方法的参数与Promise.all方法一样,如果不是 Promise 实例,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。

下面是一个例子,如果指定时间内没有获得结果,就将 Promise 的状态变为reject,否则变为resolve

const p = Promise.race([
fetch('/resource-that-may-take-a-while'),
new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error('request timeout')), 5000)
})
]); p
.then(console.log)
.catch(console.error);

原文出处http://es6.ruanyifeng.com/#docs/promise

最新文章

  1. geotrellis使用(二十三)动态加载时间序列数据
  2. DefaultAnnotationHandlerMapping 和 AnnotationMethodHandlerAdapter 的使用已经过时!
  3. (转)实例简述Spring AOP之间对AspectJ语法的支持(转)
  4. 如何用js控件div的滚动条,让它在内容更新时自动滚到底部?
  5. GC之六--SystemGC完全解读
  6. 【转】 STL中的set容器的一点总结
  7. BCP 导入导出数据库数据
  8. iOS初学者的AppStore上架应用&quot;菜谱大师&quot;开源了!
  9. asp.net mvc4 Controller与Action执行过程的研究(学习笔记)
  10. poj1881:素因子分解+素数测试
  11. Linux命令的复习总结学习
  12. 学习mysql语法--基础篇(一)
  13. sed命令基础
  14. 在虚拟机中安装Centos系统
  15. RxSwift学习笔记7:buffer/window/map/flatMap/flatMapLatest/flatMapFirst/concatMap/scan/groupBy
  16. VMware内CentOS7虚拟机硬盘扩容
  17. Java 判断字符串是否为空的四种方法、优缺点与注意事项
  18. 【洛谷p1601】A+B Problem(高精)
  19. 【Linux】Ubuntu13.10 设置静态ip地址
  20. Java与JS判断请求来是否来自移动端

热门文章

  1. streamController
  2. How do you run an interactive process in Dart?
  3. JavaScript之定时器
  4. Excel内部编码查看与验证工具
  5. yum升级curl支持http2测试
  6. Jenkins服务器的安装
  7. redis发布订阅实现各类定时业务(优惠券过期,商品不支付自动撤单,自动收货等)
  8. CSS中px,em,rem,pt的区别及四者换算?
  9. ThinkPHP模板之二
  10. 用Python添加写入数据到已经存在的Excel的xlsx文件