一、promise原理
大致的逻辑是这样的:
调用then方法,将想要在Promise异步操作成功时执行的回调放入callbacks队列,其实也就是注册回调函数,可以向观察者模式方向思考;
创建Promise实例时传入的函数会被赋予一个函数类型的参数,即resolve,它接收一个参数value,代表异步操作返回的结果,当一步操作执行成功后,用户会调用resolve方法,这时候其实真正执行的操作是将callbacks队列中的回调一一执行;
function Promise(fn) {
var value = null,
callbacks = []; //callbacks为数组,因为可能同时有很多个回调
this.then = function (onFulfilled) {
callbacks.push(onFulfilled);
return this;
};
function resolve(value) {
setTimeout(function() {
callbacks.forEach(function (callback) {
callback(value);
});
}, 0)
}
fn(resolve);
}
二、Pomise.all的使用
Promise.all可以将多个Promise实例包装成一个新的Promise实例。同时,成功和失败的返回值是不同的,成功的时候返回的是一个结果数组,而失败的时候则返回最先被reject失败状态的值。
需要特别注意的是,Promise.all获得的成功结果的数组里面的数据顺序和Promise.all接收到的数组顺序是一致的,即p1的结果在前,即便p1的结果获取的比p2要晚。这带来了一个绝大的好处:在前端开发请求数据的过程中,偶尔会遇到发送多个请求并根据请求顺序获取和使用数据的场景,使用Promise.all毫无疑问可以解决这个问题。
1.表单校验
validate(cb){
const tasks = this.$children.map(item => item.validate()) // 返回的是promise
Promise.all(tasks)
.then(()=>cb(true))
.catch(()=>cb(false))
}
2.自定义多个promise
let p1 = new Promise((resolve, reject) => {
resolve('成功了')
})
let p2 = new Promise((resolve, reject) => {
resolve('success')
})
let p3 = Promse.reject('失败')
Promise.all([p1, p2]).then((result) => {
console.log(result) //['成功了', 'success']
}).catch((error) => {
console.log(error)
})
Promise.all([p1,p3,p2]).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error) // 失败了,打出 '失败'
})
三、promise.race哪个先执行就用哪个
race的使用场景就是,多台服务器部署了同样的服务端代码,假如我要获取一个商品列表接口,我可以在 race 中写上所有服务器中的查询商品列表的接口地址,哪个服务器响应快,就从哪个服务器拿数据。
promise.race
let p1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
},1000)
})
let p2 = new Promise((resolve, reject) => {
setTimeout(() => {
reject('failed')
}, 500)
})
Promise.race([p1, p2]).then((result) => {
console.log(result)
}).catch((error) => {
console.log(error) // 打开的是 'failed'
})
四.promise.finally
new Promise((resolve,reject) => {
setTimeout(() => {
reject('hello')
}, 2000)
}).then(res => {
console.log('成功',res)
}).catch(res=>{
console.log('失败',res)
}).finally(res=>{
console.log('结束',res)
})
`
五、 promise.allSettled([p1,p2,p3])
举例说明, 比如各位用户在页面上面同时填了3个独立的表单, 这三个表单分三个接口提交到后端, 三个接口独立, 没有顺序依赖, 这个时候我们需要等到请求全部完成后给与用户提示表单提交的情况
在多个promise同时进行时咱们很快会想到使用Promise.all来进行包装, 但是由于Promise.all的短路特性, 三个提交中若前面任意一个提交失败, 则后面的表单也不会进行提交了, 这就与咱们需求不符合.
Promise.allSettled跟Promise.all类似, 其参数接受一个Promise的数组, 返回一个新的Promise, 唯一的不同在于, 其不会进行短路, 也就是说当Promise全部处理完成后我们可以拿到每个Promise的状态, 而不管其是否处理成功.
六、.链式调用,多个then,在then里面设置return new Promise
new Promise((resolve,reject) => {
setTimeout(() => {
resolve(‘hello’)
}, 2000)
}).then(res => {
console.log(‘成功’,res)
return new Promise((resolve,reject) => {
setTimeout(() => {
reject(‘hello2’)
}, 2000)
})
}).then(res => {
console.log(‘成功’,res)
}).catch(data=>
console.log(‘失败’,data)
).finally(res => console.log(‘结束’))
按钮弹框使用promise
this.$confirm(‘会在48小时内审核,请耐心等待类似信息?’, ‘提示’, {
confirmButtonText: ‘确定’,
type: ‘warning’
}).then(() => {
}).catch(() => {
});
七、异步接收promise里面的返回值。
https://www.cnblogs.com/newmiracle/p/11988774.html
function doubleAfter2seconds(num) {
return new Promise((resolve, reject) => {
resolve('2秒后触发');
} )
}
var result = await doubleAfter2seconds(1);
console.log(result);