promise的优势
项目开发中,经常会遇到顺序请求多个接口,下一个接口请求参数需要依赖上一个接口的返回值,我们会这样写:
one(function(result) {
two(result, function(newResult) {
three(newResult, function(finalResult) {
console.log(finalResult);
}, failureCallback);
}, failureCallback);
}, failureCallback);
在项目功能复杂时,嵌套更多,更深,结构向右发展,十分不利于阅读以及后期的代码维护。 我们看下promise的写法:
one().then(()=>{
return two()
}).then(()=>{
return three()
}).catch(failureCallback)
或者
let p = new Promise((resolve, reject) => {
console.log('000')
resolve(2)
});
setTimeout(() => {
p.then(value => {
console.log(value)
}).catch(err => {
console.log(err)
})
}, 1000);
由此可以看出,promise优势:
- 1 可以链式调用,解决回调地狱问题,可以统一处理异常(异常穿透)
- 2 指定回调函数的方式更加灵活, 可以在结果返回之后再指定处理函数
promise执行相关
看下面示例执行后输出什么
let p = new Promise((resolve, reject) => {
console.log('0')
resolve(2)
})
p.then(value => {
console.log('1.1>>>', value)
return '成功'
}, reason => {
console.log('1.2>>>', reason)
}).then(value => {
console.log('value>>>', value)
}, reason => {
console.log('reason>>>', reason)
})
p.then(value => {
console.log('2.1>>>', value)
return Promise.reject('5')
}).catch(err => {
console.log('2.2>>>', err)
}).then(value=>{
console.log('catch 后>>>', value)
})
setTimeout(() => {
p.then(value => {
console.log('3.1>>>', value)
}).catch(err => {
console.log('3.2>>>', err)
})
}, 0);
console.log('4')
// 打印结果:
0,
4,
1.1>>> 2,
2.1>>> 2,
value>>> 成功,
2.2>>> 5,
catch 后>>> undefined,
3.1>>> 2,
- 1) promise 执行器里的内容是同步执行的,绑定的回调函数是异步任务
- 2) 一个promise实例可以绑定多个回调函数,回调函数按序执行
- 3) 回调函数执行后会返回一个新的promise对象,该对象与之前创建的promise实例是两个不同的实例
- 4) 绑定多个回调函数时,若实例状态变为rejected、回调函数中抛出异常,被下一个回调函数处理后且没有中断promise时,后续绑定的回调函数仍会继续执行
- 5) 上一个回调函数的返回值会作为一下个回调函数的参数传入
Promise 静态方法
- Promise.all([a,b,c]) //[a,b,c] 当全部成功时,按序返回成功的值,若有一个失败,则返回第一个失败的值
- Promise.any([a,b,c]) //[a,b,c] 一个成功就成功,并返回成功的值
- Promise.race([a,b,c]) //[a,b,c] 任何一个成功或者失败,就执行,返回那个成功或者失败的值
- Promise.allSettled([a,b,c]) //[a,b,c] 按序返回所有结果,不管成功失败
- Promise.resolve(value) // 返回一个状态由给定value决定的Promise对象,若value是一个带有then方法的对象,则最终状态由then方法的返回结果决定,所以该方法不一定总是返回成功的状态
- Promise.reject(reason) // 返回一个状态为失败的Promise对象,并将给定的失败信息传递给对应的处理方法
let a = Promise.resolve(1)
let b = Promise.resolve(2)
let c = new Promise((resolve, reject) => {
setTimeout(() => {
reject('失败')
}, 1000);
})
let d = Promise.reject(4)
Promise.all([a, b, c]).then(values => {
console.log('all-success', values)
}, reason => {
console.log('all-error', reason)
})
// all-error 失败
Promise.all([a, b]).then(values => {
console.log('all-success', values)
}, reason => {
console.log('all-error', reason)
})
// [1, 2]
Promise.any([c, d, a, b]).then(values => {
console.log('any-success', values)
}, reason => {
console.log('any-error', reason)
})
// any-success 1
Promise.race([d, b, c, a]).then(values => {
console.log('race-success', values)
}, reason => {
console.log('race-error', reason)
})
// race-error 4
Promise.allSettled([a, b, c, d]).then(values => {
console.log('allSettled-success', values)
})
// [
{status: "fulfilled", value: 1},
{status: "fulfilled", value: 2},
{status: "rejected", reason: "失败"},
{status: "rejected", reason: 4}
]
let e = {
then: function (resolve, reject) {
// resolve(66)
reject(77)
},
'a': 1
}
Promise.resolve(e).then(value => {
console.log('resolve-success', value)
}, reason => {
console.log('resolve-err', reason)
})
// 打印: 77
Promise.reject(8).then().catch(reason => {
console.log('reject', reason)
})
// 8
async await
- async函数返回一个promise对象,该对象的结果由async函数执行的返回值决定
- await
- 必须写在async函数中,不可单独使用
- 若右侧是一个promise对象,则await返回的是promise的成功的值,若promise失败,则会抛出异常,需要有处理异常的语句处理
- 若右侧是其他值,则直接将此值作为await的返回值
// await 右侧返回一个失败的promise
function delay() {
return new Promise((resolve, reject) => {
setTimeout(() => {
reject(222)
}, 1000)
})
}
async function f() {
let a = await delay()
}
f().then(value => {
console.log('value', value)
}, reason => {
console.log('reject', reason)
})
//打印: reject 222
function delay1() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve(111)
}, 1000)
})
}
async function f1() {
let a = await delay1()
console.log(a)
}
f1()
// 打印 111
function delay2() {
return 333
}
async function f2() {
let a = await delay2()
console.log(a)
}
f2()
// 打印 333
以上便是最近深入了解promise后的一些总结,在遇到不了解的地方还是需要多查阅文档,从根本上解决问题。 下面贴一道测试题,欢迎评论区留下你的答案
setTimeout(() => {
console.log(1)
Promise.resolve().then(value => {
console.log(2)
})
}, 0);
new Promise((resolve, reject) => {
console.log(3)
resolve()
}).then(() => {
console.log(5)
new Promise((resolve, reject) => {
console.log(6)
resolve()
}).then(() => {
console.log(7)
}).then(() => {
console.log(8)
})
}).then(() => {
console.log(9)
})
new Promise((resolve, reject) => {
console.log(10)
resolve()
}).then(() => {
console.log(11)
})
console.log(12)