脚本宝典收集整理的这篇文章主要介绍了Promise使用须知,脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。
一.关于Promise
promise 是异步编程的一种解决方案,比传统的解决方案(回调函数和事件)更合理和更强大。它由社区最早提出和实现,ES6将其写进了语言标准,统一了用法,原生提供了Promise
对象。
所谓Promise
,简单说就是一个容器,里面保存着某个未来才会结束的事件(通常是一个异步操作)的结果。从语法上说,Promise 是一个对象,从它可以获取异步操作的消息。PRomise 提供统一的 API,各种异步操作都可以用同样的方法进行处理。
它代表一个异步操作。有三种状态:
有了Promise
,就可以将异步操作以同步操作的流程表达出,但它也有如下缺点:
二.应用示例
@H_512_53@1. 创建Promise@H_777_54@
VAR promise = new Promise(
/* executor */
function(resolve, reject){
...
}
);
executor函数由Promise实现立即执行,传递resolve和reject函数. (在Promise构造函数之前调用执行器甚至返回创建的对象)
在 executor
内部,promise有如下的状态变化可能:
1. resolve被调用,promise由pending变为resolved,代表该Promise被成功解析(resolve)
2.reject
被调用,promise由pending变为rejected,代表该Promise的值不能用于后续处理,即被拒绝了
注意:
2.处理Promise实例
-
then:Promise实例生成以后,可以用then
方法分别指定Resolved
状态和Reject
状态的回调函数。
promise.then(function(value) {
// success 状态为Resolved时调用
}, function(error) {
// failure 状态为Reject时调用
});
then
方法可以接受两个回调函数作为参数。
第一个回调函数:在promise的状态变成resolved
时被调用。它的参数promise的resolve方法的返回值。
第二个回调函数:在promise的状态变成rejected
时被调用。它的参数promise的reject方法的返回值。且为可选参数。
-
catch:Promise.prototype.catch
方法是.then(null, rejection)
的别名,用于指定发生错误时的回调函数。
promise.then(function(posts) {
// ...
}).catch(function(error) {
console.LOG('发生错误!', error); // 处理 promise 和 前一个回调函数运行时发生的错误
});
-
扩展:
-
Promise.prototype.then
和 Promise.prototype.catch
方法返回 promises对象, 所以它们可以被链式调用。但此时返回的是以函数返回值生成的新的Promise实例,不是原来那个Promise实例。
注意问题:
- Promise 对象的错误具有“冒泡”性质,会一直向后传递,直到被捕获为止。也就是说,错误总是会被下一个
catch
语句捕获。
3.将多个Promise实例,包装成一个新的Promise实例
-
Promise.all(ITerable)
:当所有在可迭代参数中的 promises 已完成,或者第一个传递的 promise(指 reject)失败时,返回 promise。
var p = Promise.all([p1, p2, P3]);
- 当p1、p2和p3的状态均为
resolved
时p的状态为resolved
。
- 当p1、p2或p3中的任意一个被
rejected
,p
的状态就变成rejected
,此时第一个被reject
的实例的返回值,会传递给p
的回调函数。
具体的使用示例如下:
-
情形一:全部成功的情况
Promise.all([Promise.resolve('foo'),Promise.resolve('bar'),Promise.resolve('test')])
.then(function(result){
console.log(result); //结果为:[foo,bar,test]。即所有返回值的数组。
})
.catch(function(error) {
console.log('error'); //不会被执行
});
-
情形二:全部失败或部分失败
Promise.all([Promise.resolve('foo'),Promise.reject('barError'),Promise.reject('testError')])
.then(function(result){
console.log(result); //成功回调 不会被执行
})
.catch(function(error) {
console.log(error); //结果为barError或testError。即第一个被reject的值。
});
@H_750_406@三.常见的使用误区
- 忘记添加 .catch()
通常情况,promise有如下两种处理方式:
// ------------ 不好的写法 -------------
promise.then(function(data) {
// success
}, function(err) { //仅处理promise运行时发生的错误。无法处理回调中的错误
// error
});
// ------------ 好的写法 ------------
promise.then(function(data) {
// success
}).catch(function(err) { // 处理 promise 和 前一个回调函数运行时发生的错误
// error
});
因为promise抛出的错误不会传递到外层代码。当使用没有catch的第一种种写法时,成功回调的错误将无法被处理。因此比较好的方式是,总是使用catch
方法。
- 在then或者catch函数中不使用return
下面是在是用Promise时,一个很常见的错误写法:
//------------ 不好的写法 ------------------
promise.then(function () {
getUserInfo(userId);
}).then(function () {
// 在这里可能希望在这个回调中使用用户信息,但你可能会发现它根本不存在
});
会发生上面的错误,是因为对Promise的返回及链式调用的理解不够。
每一个promise都会给你一个then()方法(或者catch,它们只是then(null,…)的语法糖)。这里我们是在then()方法的内部来看:
promise.then(function () {
return getUserInfo(userId);
}).then(function (userInfo) {
HadleUser(userInfo);
}).catch(function(error) {
console.log(error);
});
在回调中在有三种事可以做:
- 返回另一个promise
如果getUserInfo
返回一个Promise,则HadleUser
将在该promise变为resolved后执行,并以该promise的返回作为入参。
- 返回一个同步值(或者undefined)
getUserInfo
返回一个同步值,则改值会被包装成一个resolved状态的promise,HadleUser
将被立刻执行,并以getUserInfo返回作为入参。
-
抛出一个同步错误。
getUserInfo
返回一个同步错误,则该错误会被包装成一个rejected状态的promise,最终在catch中被捕获。此时HadleUser
将不会被执行。
- promises丢失
你认为下面的代码会打印出什么?
Promise.resolve('foo').then(Promise.resolve('bar')).then(function (result) {
console.log(result);
});
如果你认为打印出bar,那你就大错特错了。它实际上会打印出foo。
原因是当你给then()传递一个非函数(比如一个promise)值的时候,它实际上会解释为then(null),这会导致之前的promise的结果丢失。
四.最佳实践总结
参考链接:
以上是脚本宝典为你收集整理的Promise使用须知全部内容,希望文章能够帮你解决Promise使用须知所遇到的问题。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。