Promise的字面意思就是"承诺",是对未来发生事情成功与否的承诺,所以要么是成功 ,即将pending(等待)状态转为fullfilled(成功)状态,否则将pending状态转为rejected(失败),所以由此可知,Promise是一种异步操作。这是不是让我们想到了ajax?对!ajax就是将Promise进行封装得来的。(阅读这篇文章之前,最好具备es6简单语法的技能,比如const,箭头函数等)
Promise的简单介绍
我们常常会用到在一个函数里面调用另一个函数,另一个函数里面再调用其他的函数,层层嵌套,会让我们的代码看上去结构很深,不易理解,比如下面的例子:
const testFun1 = function(callback) {
console.log('我其实被回调啦1')
callback()
}
const testFun2 = function(callback) {
console.log('我其实被回调啦2')
callback()
}
const testFun3 = function(callback) {
console.log('我其实被回调啦3')
callback()
}
const testFun4 = function(callback) {
console.log('我其实被回调啦4')
callback()
}
testFun1((test1) => {
testFun2((test2) => {
testFun3((test3) => {
testFun4((test4) => {
//dosomethings
console.log('被执行啦')
})
})
})
})
结果:
我其实被回调啦1
我其实被回调啦2
我其实被回调啦3
我其实被回调啦4
被执行啦
上面的操作是可以实现功能,但是在写法上,可能会让我们陷入"回调地狱",我们可以通过Promise.all()来解决这一问题。每一个回调函数都返回一个Promise实例,回调函数的执行是根据上一个函数的执行结果来判断。如果成功,则执行resolve,将值往下传递,否则catch error,如果error,那么后面的回调函数将被跳过,不再被执行,并且返回错误信息。
function test1() {
let pro = new Promise(resolve => {
resolve('我其实被回调啦1')
})
return pro
}
function test2() {
let pro = new Promise(resolve => {
resolve('我其实被回调啦2')
})
return pro
}
function test3() {
let pro = new Promise(resolve => {
resolve('我其实被回调啦3')
})
return pro
}
Promise
.all([test1(), test2(), test3()])
.then(resolve => {
console.log(resolve)
})
.catch(error => {
console.log(error)
})
结果:
[ '我其实被回调啦1', '我其实被回调啦2', '我其实被回调啦3' ]
Promise的简单用法
1.Promise的常见用法---链式调用。
有的业务中,需要对操作异步实现多个功能,可以用链式调用,即在Promise的then里面返回一个promise即可,他会将上一层的值带到下一个then函数里面。如果返回的是值,那么直接返回该值,否则将resolve的值传递下去。
function test() {
return new Promise((resolve, reject) => {
resolve('start1')
})
}
function test2() {
return new Promise((resolve, reject) => {
resolve('start2')
})
}
function test3() {
return new Promise((resolve, reject) => {
resolve('start3')
})
}
test()
.then((resolve) => {
console.log(resolve);
return test2()
})
.then((resolve) => {
console.log(resolve);
return test3()
})
.then((resolve) => {
console.log(resolve);
})
.catch((reject) => {
console.log(reject)
})
结果:
start1
start2
start3
function test() {
return new Promise((resolve, reject) => {
setTimeout(function() {
resolve('start1')
}, 1000)
})
}
function test2() {
return new Promise((resolve, reject) => {
resolve('start2')
})
}
function test3() {
return new Promise((resolve, reject) => {
setTimeout(function() {
resolve('start3')
}, 1000)
})
}
test()
.then((resolve) => {
console.log(resolve);
return '1'
})
.then((resolve) => {
console.log(resolve);
return test3()
})
.then((resolve) => {
console.log(resolve);
})
.catch((reject) => {
console.log(reject)
})
结果:
start1 //1s后打印
1 //1s后打印 与start1同时出现
start3 //再过1s后打印
2.上面我们简单介绍了Promise.all(),下面我们将介绍Promise.all(),Promise.race()的一些详细用法。如果我们在业务中,对then方法里面的执行顺序没有过多的要求,我们如果一个个的去写的话 ,像上面提到的多个函数(test1,test1,test3),就比较麻烦了,这个时候我们就可以用到Promise.all(),Promise.race()了。
Promise.all()
/*
**
all:以最慢的为结束标志,以数组的形式,返回所有的promise实例的结果
**
*/
function test1() {
let pro = new Promise(resolve => {
setTimeout(() => {
console.log('start1');
resolve('我其实被回调啦1')
}, 1000)
})
return pro
}
function test2() {
let pro = new Promise(resolve => {
setTimeout(() => {
console.log('start2');
resolve('我其实被回调啦2')
}, 2000)
})
return pro
}
function test3() {
let pro = new Promise(resolve => {
setTimeout(() => {
console.log('start3');
resolve('我其实被回调啦3')
}, 3000)
})
return pro
}
Promise
.all([test1(), test2(), test3()])
.then(resolve => {
console.log(resolve)
})
.catch(error => {
console.log(error)
})
结果:
start1 //1s后打印
start2 //2s后打印
start3 //3s后打印
[ '我其实被回调啦1', '我其实被回调啦2', '我其实被回调啦3' ] //3s后打印
Promise.race()
/*
**
race:谁跑的快谁先被调用
**
*/
function test1() {
let pro = new Promise(resolve => {
setTimeout(() => {
console.log('start1');
resolve('我其实被回调啦1')
}, 1000)
})
return pro
}
function test2() {
let pro = new Promise(resolve => {
setTimeout(() => {
console.log('start2');
resolve('我其实被回调啦2')
}, 2000)
})
return pro
}
function test3() {
let pro = new Promise(resolve => {
setTimeout(() => {
console.log('start3');
resolve('我其实被回调啦3')
}, 500)
})
return pro
}
Promise
.race([test1(), test2(), test3()])
.then(resolve => {
console.log(resolve)
})
.catch(error => {
console.log(error)
})
结果:
start3 //500ms打印
我其实被回调啦3 //500ms打印
start1 //1s打印
start2 //2s打印
Promise.all()与Promise.race()相比,前者是谁执行得最慢,所有的结果就以最慢的为标准,一起被返回回来,但是后者不同,谁执行的最快,谁被回调,其余的不被回调。这里的回调是指resolve里面的代码。
另附:我不知道你们有没有这样的疑惑,前面明明说了Promise的结果只有成功和失败两种,为啥后文说到的Promise,他的后面可以跟多个then,看上去感觉他可以执行多个操作,返回不同的结果。其实不是这样的,仔细看之前的代码,每个then的里面其实是对上一个promise成功与否的记录或者说值得传递,想要继续将本次的值在下面的then中去执行,那么要在本次的then中返回一个promise实例。简单的说,then里面返回一个promise实例,会形成链式调用,将上一次的值带入下一个promise里面,再进行操作,这也是Promise的强大之处,异步执行不同的操作。所谓异步,就是不用等待上一步操作完成后,结果出来后,本次的执行才能继续,而是各司其职,共同完成,因为在Promise里面,我已经事先指派好了,成功要执行resolve,失败要执行reject,所以不用等待,而是按照定义好的步骤,统一执行。效率棒棒哒~~~~~