Promise是es6中解决回调地狱一种同步优雅写法。promise.then作为微任务队列中的一种异步,优先级高于宏任务。promise有三种状态:pending,resovle和reject,状态总是由pending向resolve和reject转换。下面来讲述几个基本用法。
1.promise.then、promise.resovle、promise.reject
function PromiseDemo(){
new Promise((resolve, reject) =>{
resolve({data:['linjian is test']});
}).then((value)=>{
console.log(value);
})
Promise.resolve({data:'这是异步'}).then((value)=>{
console.log('resolve异步', value)
});
Promise.reject({data:'这是reject异步'}).then((value) =>{
console.log('reject异步', value)
})
}
PromiseDemo();
输出结果
{ data: [ 'linjian is test' ] }
resolve异步 { data: '这是异步' }
(node:6940) UnhandledPromiseRejectionWarning: #<Object>
(node:6940) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 2)
(node:6940) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
这是几种最基本异步,上面我们发现reject中必须添加catch捕捉异常,所以最后修改如下:
Promise.reject({data:'这是reject异步'}).then((value) =>{
console.log('reject异步', value)
}).catch((e)=>{
console.log('e:', e)
})
输出: e: { data: '这是reject异步' }
下面讲述Promise.all和Promise.race用法
1.Promise.all很明显就是等待所有的Promise完成后才返回结果,这种在我们异步请求几个API时,要等待所有结果返回后再处理非常有用。
const p1 = new Promise((resolve, reject) => {
setTimeout(() =>{
resolve({data:'这个promise1'})
}, 5000);
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() =>{
resolve({data:'这个promise2'})
}, 1000);
})
Promise.all([p1,p2]).then((value) =>{
console.log('Promise.all', value)
})
输出:Promise.all [ { data: '这个promise1' }, { data: '这个promise2' } ]
这里我们看到Promise.all把所有结果一次性返回,而且返回的顺序跟all入参数组一样,不管执行时间的长短顺序。
Promise.race([p1, p2]).then((value)=>{
console.log('Promise.race:', value);
})
输出结果:Promise.race: { data: '这个promise2' }
Promise.race是谁快返回谁。
如果Promise.all中某个promise发生异常,可以通过主动reject和catch的方式,保证所有的promise返回结果。
const p1 = new Promise((resolve, reject) => {
setTimeout(() =>{
resolve({data:'这个promise1'})
}, 5000);
}).catch((value)=>{
return '这是catch1说明'
})
const p2 = new Promise((resolve, reject) => {
setTimeout(() =>{
reject({data:'这个promise2'})
}, 1000);
}).catch((value)=>{
return '这是catch2说明'
})
Promise.all([p1,p2]).then((value) =>{
console.log('Promise.all', value)
})
输出结果:
Promise.all [ { data: '这个promise1' }, '这是catch2说明' ]
promise串联,可以同时建立多个promise,在then阶段取数的时候,可以有序的取数。
console.log('promise 链式调用')
const p3 = () => new Promise((resolve, reject) => {
resolve({data: 'china'})
})
const p4 = (data) => {
console.log(data)
return new Promise((resolve, reject) => {
resolve({data: 'guangdong'})
})
}
const p5 = (data) => {
console.log(data)
return new Promise((resolve, reject) => {
resolve({data: 'shenzhen'})
})
}
p3().then(p4).then(p5).then((data) => {
console.log(data)
})
输出结果:
promise 链式调用
{ data: 'china' }
{ data: 'guangdong' }
{ data: 'shenzhen' }
这里要注意是链式调用,上一个结果会成为下一个promise的入参,所以要在下一个promise中取结果。
上面这种例子有个问题,如果是遇到有reject操作,会直接抛出异常,终止后续promise的执行,例子如下:
console.log('promise 链式调用')
const p3 = () => new Promise((resolve, reject) => {
resolve({data: 'china'})
})
const p4 = (data) => {
console.log(data)
return new Promise((resolve, reject) => {
resolve({data: 'guangdong'})
})
}
const p5 = (data) => {
console.log(data)
return new Promise((resolve, reject) => {
resolve({data: 'shenzhen'})
})
}
const p6 = (data) => {
console.log(data);
return new Promise((resolve, reject) => {
reject('这是错误结果');
})
}
p3().then(p6).then(p4).then(p5).then((data) => {
console.log(data)
}).catch((value) => {
console.log('捕捉异常', value)
})
输出结果:
promise 链式调用
{ data: 'china' }
捕捉异常 这是错误结果
我们可以通过内部捕捉异常,防止整条链子都终止执行
const p6 = (data) => {
console.log(data);
return new Promise((resolve, reject) => {
reject('这是错误结果');
}).catch((value) => {
console.log('内部捕捉异常', value)
})
}
执行结果:
promise 链式调用
{ data: 'china' }
内部捕捉异常 这是错误结果
undefined
{ data: 'guangdong' }
{ data: 'shenzhen' }
所以内部捕捉异常之后,就不会把异常抛到外部链式promise上,就不会影响到整个链子的执行了
网友评论