以前我们经常这么写异步回调:
step1(function(val1) {
step2(function(val2) {
step3(function(val3){
// ...嵌套再嵌套
})
})
})
这种三角形代码缺陷显而易见:
- 代码不优雅,阅读费劲
- 难以维护,俗称回调地狱
然后我们应用es6中promise:
new Promise(step1())
.then(step2())
.then(step3())
// 。。。是不是很帅?
promise以同步的方式来写异步,不用担心错过某个事件或信号,它是等上一个异步操作有结果了再执行它所寄存的下一个操作
几个需要注意的点:
- promise有三种状态 等待(pending)、已完成(fulfilled)、已拒绝(rejected)
- promise的状态只能从“等待”转到“完成”或者“拒绝”,不能逆向转换,同时“完成”和“拒绝”也不能相互转换
- promise必须有一个then方法,并且要返回一个promise对象,供then的链式调用
- then接受两个回调(成功与拒绝),在相应的状态转变时触发,回调可返回promise,等待此promise被resolved后,继续触发then链
##基本用法
ES6的promise对象是一个构造函数,用来生成promise实例。
var promise = new Promise((resolve, reject) => {
if (/* 异步操作成功 */) {
resolve(value)
} else {
reject(error)
}
})
promise.then(onFulfilled,onRejected).then(onFulfilled,onRejected)
这是我们项目中常用的方法,大家并不陌生。但还是说一下大概原理,Promise构造函数接受一个函数作为参数,该函数的两个参数分别是resovle和reject方法。异步操作成功时,则用resolve方法将promise对象的状态改为“成功”;异步操作失败时,则用reject方法将状态改为“失败”。 promise实例生成以后,then传入回调,这里 的函数并不会立即执行而是加入队列,等待未来resolve或reject时触发执行。
###Promise.prototype.then()
function getPromise(n) {
return new Promise((resovle, reject) => {
if(n <= 100) {
resovle(n)
} else {
reject('请传入100以内的数值!')
}
})
}
首先我先实例化一个Promise,之后介绍的方法都调用此函数作为例子
getPromise(1).then((a) => {
return a + 1
}).then((b) => {
console.log(b)
})
// 结果:2 2
then方法依次指定了两个函数,第一个回调函数返回的值传递给下一个函数作为参数。这种设计使得嵌套的异步操作得以改写。
###Promise.prototype.catch()
Promise.prototype.catch方法是Promise.prototype.then(null, rejection)的别名,用于指定发生错误时的回调函数。
getPromise(101).then((value) => {
console.log(value)
}).catch((error) => {
console.log(error)
})
// 结果:请传入100以内的数值!
###Promise.all()
var p = Promise.all([p1,p2,p3]);
接受一个数组作为参数 p1,p2,p3都是Promise对象的实例 p的状态由p1,p2,p3决定 返回为一个新的promise实例 先个例子吧:
var p = [1, 2, 3].map((time) => {
return getPromise(time)
})
Promise.all(p).then((arrs) => {
console.log(arrs)
})
// 结果:[1,2,3]
###Promise.race()
var p = Promise.race([p1,p2,p3]);
race与all方法不同之处在于p1,p2,p3之中有一个实例率先改变状态,p的状态就跟着改变。率先改变的Promise实例的返回值,就传递给p的回调函数。这里例子就不写了,有兴趣的同学可以去试试。
###Promise.resolve()与Promise.reject()
这两个方法的特色之处是将其参数转换成一个新的Promise对象
###错误的观念
有一次我看到有个人的代码里这么用promise, 那一刻我怀疑自己的眼睛瞎了,虽然结果没有什么问题,但是思想没有转变,还是原来的传统回调思想,失去了使用promise的意义
来看一下错误的写法:
// 错误的写法
getPromise(1)
.then((a) => {
console.log(a)
return getPromise(a+1)
.then((b) => {
console.log(b)
return getPromise(b+1)
.then((c) => {
console.log(c)
})
})
})
//结果:1
// 2
// 3
// 正确的写法
getPromise(1)
.then((a) => {
console.log(a)
return a+1
})
.then((b) => {
console.log(b)
return b+1
})
.then((c) => {
console.log(c)
return c+1
})
//结果:1
// 2
// 3
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!