想必接触过Node的人都知道,Node是以异步(Async)回调著称的,其异步性提高了程序的执行效率,但同时也减少了程序的可读性。如果我们有几个异步操作,并且后一个操作需要前一个操作返回的数据才能执行,这样按照Node的一般执行规律,要实现有序的异步操作,通常是一层加一层嵌套下去。 为了解决这个问题,ES6提出了Promise的实现。
含义 Promise 对象用于一个异步操作的最终完成(或失败)及其结果值的表示。简单点说,它就是用于处理异步操作的,异步处理成功了就执行成功的操作,异步处理失败了就捕获错误或者停止后续操作。 它的一般表示形式为:
new Promise(
/* executor */
function(resolve, reject) {
if (/* success */) {
// ...执行代码
resolve();
} else { /* fail */
// ...执行代码
reject();
}
}
);
其中,Promise中的参数executor是一个执行器函数,它有两个参数resolve和reject。它内部通常有一些异步操作,如果异步操作成功,则可以调用resolve()来将该实例的状态置为fulfilled,即已完成的,如果一旦失败,可以调用reject()来将该实例的状态置为rejected,即失败的。
我们可以把Promise对象看成是一条工厂的流水线,对于流水线来说,从它的工作职能上看,它只有三种状态,一个是初始状态(刚开机的时候),一个是加工产品成功,一个是加工产品失败(出现了某些故障)。同样对于Promise对象来说,它也有三种状态:
var promise1 = new Promise(function(resolve, reject) {
// 2秒后置为接收状态
setTimeout(function() {
resolve('success');
}, 2000);//欢迎加入全栈开发交流圈一起学习交流:864305860
});//面向1-3年前端人员
//帮助突破技术瓶颈,提升思维能力
promise1.then(function(data) {
console.log(data); // success
}, function(err) {
console.log(err); // 不执行
}).then(function(data) {
// 上一步的then()方法没有返回值
console.log('链式调用:' + data); // 链式调用:undefined
}).then(function(data) {
// ....
});
我们主要关注promise1.then()方法调用后返回的Promise对象的状态,是pending还是fulfilled,或者是rejected?
var promise2 = new Promise(function(resolve, reject) {
// 2秒后置为接收状态
setTimeout(function() {
resolve('success');
}, 2000);
});
promise2
.then(function(data) {
// 上一个then()调用了resolve,置为fulfilled态
console.log('第一个then');
console.log(data);
return '2';
})
.then(function(data) {
// 此时这里的状态也是fulfilled, 因为上一步返回了2
console.log('第二个then');
console.log(data); // 2
return new Promise(function(resolve, reject) {
reject('把状态置为rejected error'); // 返回一个rejected的Promise实例
});
}, function(err) {
// error
})//欢迎加入全栈开发交流圈一起学习交流:864305860
.then(function(data) {
/* 这里不运行 */
console.log('第三个then');
console.log(data);
// ....
}, function(err) {
// error回调
// 此时这里的状态也是fulfilled, 因为上一步使用了reject()来返回值
console.log('出错:' + err); // 出错:把状态置为rejected error
})//欢迎加入全栈开发交流圈一起学习交流:864305860
.then(function(data) {
// 没有明确指定返回值,默认返回fulfilled
console.log('这里是fulfilled态');
});//欢迎加入全栈开发交流圈一起学习交流:864305860
Promise.prototype.catch() catch()方法和then()方法一样,都会返回一个新的Promise对象,它主要用于捕获异步操作时出现的异常。因此,我们通常省略then()方法的第二个参数,把错误处理控制权转交给其后面的catch()函数,如下:
var promise3 = new Promise(function(resolve, reject) {
setTimeout(function() {
reject('reject');
}, 2000);
});
promise3.then(function(data) {
console.log('这里是fulfilled状态'); // 这里不会触发
// ...
}).catch(function(err) {
// 最后的catch()方法可以捕获在这一条Promise链上的异常
console.log('出错:' + err); // 出错:reject
});
Promise.all() Promise.all()接收一个参数,它必须是可以迭代的,比如数组。 它通常用来处理一些并发的异步操作,即它们的结果互不干扰,但是又需要异步执行。它最终只有两种状态:成功或者失败。 它的状态受参数内各个值的状态影响,即里面状态全部为fulfilled时,它才会变成fulfilled,否则变成rejected。 成功调用后返回一个数组,数组的值是有序的,即按照传入参数的数组的值操作后返回的结果。如下:
// 置为fulfilled状态的情况
var arr = [1, 2, 3];
var promises = arr.map(function(e) {
return new Promise(function(resolve, reject) {
resolve(e * 5);
});
});
Promise.all(promises).then(function(data) {
// 有序输出
console.log(data); // [5, 10, 15]
console.log(arr); // [1, 2, 3]
});
// 置为rejected状态的情况
var arr = [1, 2, 3];
var promises2 = arr.map(function(e) {
return new Promise(function(resolve, reject) {
if (e === 3) {
reject('rejected');
}//欢迎加入全栈开发交流圈一起学习交流:864305860
resolve(e * 5);//面向1-3年前端人员
});//帮助突破技术瓶颈,提升思维能力
});
Promise.all(promises2).then(function(data) {
// 这里不会执行
console.log(data);
console.log(arr);
}).catch(function(err) {
console.log(err); // rejected
});
Promise.race() Promise.race()和Promise.all()类似,都接收一个可以迭代的参数,但是不同之处是Promise.race()的状态变化不是全部受参数内的状态影响,一旦参数内有一个值的状态发生的改变,那么该Promise的状态就是改变的状态。就跟race单词的字面意思一样,谁跑的快谁赢。如下:
var p1 = new Promise(function(resolve, reject) {
setTimeout(resolve, 300, 'p1 doned');
});
//欢迎加入全栈开发交流圈一起学习交流:864305860
var p2 = new Promise(function(resolve, reject) {
setTimeout(resolve, 50, 'p2 doned');
});
//欢迎加入全栈开发交流圈一起学习交流:864305860
var p3 = new Promise(function(resolve, reject) {
setTimeout(reject, 100, 'p3 rejected');
});
//欢迎加入全栈开发交流圈一起学习交流:864305860
Promise.race([p1, p2, p3]).then(function(data) {
// 显然p2更快,所以状态变成了fulfilled
// 如果p3更快,那么状态就会变成rejected
console.log(data); // p2 doned
}).catch(function(err) {
console.log(err); // 不执行
});
Promise.resolve() Promise.resolve()接受一个参数值,可以是普通的值,具有then()方法的对象和Promise实例。正常情况下,它返回一个Promise对象,状态为fulfilled。但是,当解析时发生错误时,返回的Promise对象将会置为rejected态。如下:
// 参数为普通值
var p4 = Promise.resolve(5);
p4.then(function(data) {
console.log(data); // 5
});
// 参数为含有then()方法的对象
var obj = {
then: function() {
console.log('obj 里面的then()方法');
}
};
var p5 = Promise.resolve(obj);
p5.then(function(data) {
// 这里的值时obj方法里面返回的值
console.log(data); // obj 里面的then()方法
});
// 参数为Promise实例
var p6 = Promise.resolve(7);
var p7 = Promise.resolve(p6);
p7.then(function(data) {
// 这里的值时Promise实例返回的值
console.log(data); // 7
});
// 参数为Promise实例,但参数是rejected态
var p8 = Promise.reject(8);
var p9 = Promise.resolve(p8);
p9.then(function(data) {
// 这里的值时Promise实例返回的值
console.log('fulfilled:'+ data); // 不执行
}).catch(function(err) {
console.log('rejected:' + err); // rejected: 8
});//欢迎加入全栈开发交流圈一起学习交流:864305860
Promise.reject() Promise.reject()和Promise.resolve()正好相反,它接收一个参数值reason,即发生异常的原因。此时返回的Promise对象将会置为rejected态。如下:
var p10 = Promise.reject('手动拒绝');
p10.then(function(data) {
console.log(data); // 这里不会执行,因为是rejected态
}).catch(function(err) {
console.log(err); // 手动拒绝
}).then(function(data) {
// 不受上一级影响
console.log('状态:fulfilled'); // 状态:fulfilled
});//欢迎加入全栈开发交流圈一起学习交流:864305860
除非Promise.then()方法内部抛出异常或者是明确置为rejected态,否则它返回的Promise的状态都是fulfilled态,即完成态,并且它的状态不受它的上一级的状态的影响。 结语
Promise 想必大家十分熟悉,想想就那么几个 api,可是你真的了解 Promise 吗?本文根据 Promise 的一些知识点总结了十道题,看看你能做对几道。
本文写给有一定Promise使用经验的人,如果你还没有使用过Promise,这篇文章可能不适合你,Promise标准中仅指定了Promise对象的then方法的行为,其它一切我们常见的方法/函数都并没有指定.
Async/Await替代Promise的6个理由:Async/Await是近年来JavaScript添加的最革命性的的特性之一。它会让你发现Promise的语法有多糟糕,而且提供了一个直观的替代方法。
Promise是JS异步编程中的重要概念,异步抽象处理对象,是目前比较流行Javascript异步编程解决方案之一,Promise 是一个构造函数, new Promise 返回一个 promise对象 接收一个excutor执行函数作为参数
这篇文章是考虑如何自己实现一个简单 Promise,用以理解 Promise。和原生 Promise的调用方法一样,支持链式调用,本文实现的方法只能用于参考Promise的原理,还有很多特性没有实现,比如 race,all 方法的实现。
在对数组进行一些遍历操作时,发现有些遍历方法对Promise的反馈并不是我们想要的结果。async/await为Promise的语法糖,文中会直接使用async/await替换Promise;map可以说是对Promise最友好的一个函数了,
最近在使用axios库时遇到了个问题,后端接口报了500错误,但前端并未捕获到。在axios整体配置的代码中,过滤http code时,调用了filter401()、filter500(),但是这里注意并未将两个filter函数的结果返回,也就是并未返回promise,这就是导致问题出现的原因
你可以在 .then 里面 return 一个 Promise,每次执行 .then 的时候都会自动创建一个新的 Promise,对调用者来说,Promise 的 resolved/rejected 状态是唯一的,Promise 构造函数不是解决方案,使用 Promise.resolve
Promise的一些用法在此不多赘述,本篇主要带领你手写一个Promise源码,学完你就会发现:Promise没有你想象中的那么难.本篇大概分为以下步骤:实现简单的同步Promise、增加异步功能、增加链式调用then、增加catch finally方法、增加all race 等方法、实现一个promise的延迟对象defer、最终测试
首先来分析一下then then是属于实例上的方法 参数有2个,分别为onFulfilled, onRejected,并且都是可选的、可以实现链式调用、then执行要执行Promise onFulfilled 或者 onRejected 方法、参数onFulfilled,onRejected 分别有自己的参数, 分别是resolve的参数跟reject的参数、then只能使用前一个then的返回值、then返回值不能是同一个promise
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!