Promise 对象代表着一个还未完成,但预期将来会完成的操作,该新特性属于 ECMAScript 2015(ES6)规范。
使用 Promise 对象,可以十分方便的摆脱层层嵌套的异步操作回调函数,而以同步操作的流程书写代码。
Promise 对象主要具有以下两个特点:
Promise对象的状态只受构造函数内的同步或者一步操作影响,其他外部操作无法改变Promise对象的状态。Promise对象的状态改变,只会从pending变为resolved或者从pending变为rejected,状态改变后不再会发生改变。
浏览器兼容性
Promise Constructor
Promise 对象构造器接受一个带有 resolve 和 reject 两个参数的函数,resolve 用于处理执行成功的场景,reject 用于处理执行失败的场景,我们可以根据执行结果决定调用哪个函数处理。
new Promise(function(resolve, reject) { … });
Promise对象有以下几种状态:
- pending: 初始状态;
- resolved: 成功的操作,又称fulfilled;
- rejected: 失败的操作。
示例如下:
var promiseCount = 0; function testPromise() {
var thisPromiseCount = ++promiseCount; console.log(thisPromiseCount + ') 开始(同步代码开始)'); // 我们创建一个新的promise: 然后用'result'字符串完成这个promise (3秒后) var p1 = new Promise(function (resolve, reject) {
// 完成函数带着完成(resolve)或拒绝(reject)promise的能力被执行 console.log(thisPromiseCount + ') Promise开始(异步代码开始)'); console.log('//等待若干秒'); // 这只是个创建异步完成的示例 window.setTimeout(function () {
// 我们满足(fullfil)了这个promise! resolve(thisPromiseCount) }, Math.random() * 2000 + 1000); }); // 定义当promise被满足时应做什么 p1.then(function (val) {
// 输出一段信息和一个值 console.log(val + ') Promise被满足了(异步代码结束)'); }); console.log(thisPromiseCount + ') 建立了Promise(同步代码结束)'); } testPromise(); testPromise(); testPromise();
讯享网
输出:
讯享网1) 开始(同步代码开始) 1) Promise开始(异步代码开始) //等待若干秒 1) 建立了Promise(同步代码结束) 2) 开始(同步代码开始) 2) Promise开始(异步代码开始) //等待若干秒 2) 建立了Promise(同步代码结束) 3) 开始(同步代码开始) 3) Promise开始(异步代码开始) //等待若干秒 3) 建立了Promise(同步代码结束)
Promise 对象和其原型对象定义几个非常有用的方法:
Promise.prototype.then
then() 方法接收两个函数作为参数,并分别作为 success 和 failure 状态的回调函数,then() 方法返回一个 Promise 对象。
语法:
then() 的第二个参数通常省略,因为无法捕获当前then() 函数的异常,而用统一的 catch() 函数进行异常处理,下节详述
then() 使用:
then() 方法返回 Promise 对象,因此可以链式调用,而前一个 then() 函数的返回值将会被作为参数传递给下一个 then() 函数:
var p = new Promise(function(resolve, reject) {
resolve("SUCCESS"); //or //reject("FAILURE"); }); p.then(function(succData){
console.log(succData);//success }, function(errData){
console.log(errData);//failure });
链式调用:
then() 方法返回 Promise 对象,因此可以链式调用,而前一个 then() 函数的返回值将会被作为参数传递给下一个 then() 函数:
讯享网var p = new Promise(function(resolve, reject) {
resolve(1); }); p.then(function(val) {
console.log(val); // 1 return val + 1; }).then(function(val) {
console.log(val); // 2 }).then(function(val) {
console.log(val); // 3 });
Promise.prototype.catch
catch() 函数处理 Promise 失败的情形,即在 Promise 中调用了 reject(data) 的情形, 也可以捕获 then() 函数中抛出的错误。
语法:
p.catch(function(errData){})
catch使用
var p = new Promise(function(resolve, reject) {
//resolve("SUCCESS"); //or reject("FAILURE"); }); p.then(function(succData){
console.log(succData);//success }).catch(function(errData){
console.log(errData);//failure }); //实际上等同于 p.then(function(succData){
console.log(succData);//success }.then(null, function(errData){
console.log(errData);//failure });
捕获 Promise 的错误
catch 也能捕获 promise语句中的错误,这种情况类似于在 promise 中调用 reject。

讯享网var p = new Promise(function(resolve, reject) {
throw("FAILURE"); }); p.then(function(succData){
throw new Error('FAILURE'); //不执行 }).catch(function(errData){
console.log(errData);//FAILURE });
捕获 then 函数的错误
var p = new Promise(function(resolve, reject) {
resolve("SUCCESS"); }); p.then(function(succData){
throw new Error('FAILURE'); }).catch(function(errData){
console.log(errData);//FAILURE });
catch 也支持链式调用
Promise 的错误总是向后抛给 catch 处理的,而 catch 的返回值也是 Promise 因此后一个 catch() 可以处理前一个 catch() 中抛出的错误
建议统一使用 catch 处理异常
尽管通过 then() 方法传递第二个参数可以处理异常,但是无法处理此个 then() 内的异常:
讯享网var p = new Promise(function(resolve, reject) {
reject(FAILURE1); }); p.catch(function(errData){
console.log(errData);//FAILURE1 throw new Error('FAILURE2'); }).catch(function(errData){
console.log(errData);//FAILURE2 });
Promise.all
Promise.all 方法是 Promise 的一个静态方法,将多个 promise 实例(p1, p2, p3)包装成一个新的 promise 实例(p),此时会有两种执行结果:
1. p 会等所有 promise( p1, p2, p3 )都被 resolve 后 resolve,此时将这些 promise ( p1, p2, p3 )的返回值组成一个数组([p1,p2,p3]),传递给 p 的回调函数;
2. 如果 p1, p2, p3 中有一个被 reject 则该 reject ,并将该 reject的返回值传递给 p 的回调函数 。
语法:
Promise.all(iterable)
iterable 是一个可迭代对象,比如 Array,iterable 元素可以不是 promise 如果不是 promise 则会使用 Promise.resolve 转换为 Promise。
从多个数据源获取数据
下面是使用 ajax 从多个不同的接口获取数据的示例,如果所有的数据都获取成功,就可以渲染页面,否则报错。
p = Promise.race([ fetch('/resource/data1.json'), fetch('/resource/data2.json'), fetch('/resource/data3.json'), ]).then(([d1, d2, d3]) => { //render page }).catch(err => { //err handler });
Promise.race
Promise.race 方法是 Promise 的一个静态方法,将多个 promise 实例包装成一个新的 promise 实例,和 Promise.all 不同的是,这多个 promise 实例中的任意一个 promise 被解决或拒绝后,立刻以该 promise 的状态和传递的值返回给其回调函数,方法返回一个 Promise。
语法:
Promise.race(iterable) //iterable:一个可迭代对象,比如Array。
处理 ajax 异常状态
下面是使用 ajax 获取数据的示例,第二个 promise 在5s后状态会变为 reject ,如果 fetch 在5s 内获取导数据将会正常执行,否则会触发超时错误。
讯享网p = Promise.race([ fetch('/resource/data.json'), new Promise(function (resolve, reject) {
setTimeout(() => reject(new Error('request timeout')), 5000) }) ]).then(response => { //use data do sth }).catch(error => { //err handler })
Promise.resolve
Promise.resolve 方法将给定的参数转换为一个 Promise 对象,
语法:
Promise.resolve(value);
Promise.resolve(promise);
Promise.resolve(thenable);
参数是 promise 对象
参数是 promise 对象,则不做操作直接返回这个 promise 对象。
Promise.resolve(Promise.resolve('Hello, world')).then(data => console.log(data));
参数是 thenable 对象
如果参数是一个包含 then 方法的对象,resolve 方法会将这个对象转为 Promise 对象,然后执行这个对象的 then 方法。
讯享网Promise.resolve({ then(resolve, reject) { resolve('Hello, world'); } }).then(data => console.log(data));//Hello, world
参数不是 thenable 和 promise 对象
如果参数是一个数值,或者是一个非 thenable 或非 promise 的对象,Promise.resolve 方法返回一个状态为 Resolved 的 promise 对象,并把这个参数作为返回值传递给 then 回调函数(如果存在 then 的回调)。
Promise.resolve('Hello, world').then(data => console.log(data)); //Hello, world
Promise.reject
Promise.reject 方法将给定的参数转换为一个 Promise 对象,
语法:
Promise.reject(value);
Promise.reject(promise);
Promise.reject(thenable);
具体的使用情况与 Promise.resolve 类似。
参考:
- Promise
- Promise对象

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容,请联系我们,一经查实,本站将立刻删除。
如需转载请保留出处:https://51itzy.com/kjqy/128961.html