1. Promise 基本用法
Promise:是异步编程的一种解决方案,比较传统的解决方案(回调函数)更合理和强大。
有三种状态:pending(进行中)、fufilled(已成功)、rejected(已失败)
function getDate(val) {
return new Promise((resolve, reject) => {
if (val) {
resolve('成功')
} else {
reject('error')
}
})
}
// 执行:then可以接收两个函数,第一个表示已成功的(resolve),第二个表示已失败的(reject)第二个函数可以选填
// 写法一:
getDate(true).then((res) => {
console.log(res)
}, (err) => {
console.log(err)
}).finally(() => {
// finally 不管成功或者失败都会执行,类似于try-catch-finally
console.log('finally1')
console.log('----------------------------')
})
// 写法二:注意当then()第二个函数存在时会忽略catch()
getDate(false).then((res) => {
console.log(res)
}).catch(err => {
console.log(err, 'err2')
}).finally(() => {
console.log('finally2')
})
// getDate(false).then((res) => {
// console.log(res)
// }, (err) => {
// console.log(err, 'err3-1')
// }).catch(err => {
// console.log(err, 'err3-2')
// }).finally(() => {
// console.log('finally3')
// })
Promise.resolve('abc')
// 等价于
new Promise(resolve => resolve('abc'))
Promise.reject('abc')
// 等价于
new Promise(resolve => reject('abc'))
2. Promise.all([])
该方法用于将多个 Promise 实例,包装成一个新的 Promise 实例
全部成功调用then(),其中一个失败调用catch(),不会执行then()
function getDate(val) {
return new Promise((resolve, reject) => {
if (val) {
resolve('成功')
} else {
reject('error')
}
})
}
function getName() {
return 'Martin'
}
// Promise.all([
// getDate(true),
// getDate(false),
// getDate(true)
// ]).then(res => {
// console.log(res)
// }).catch(err => {
// console.log(err) // error
// })
// Promise.all()方法接受一个数组作为参数,如果不是Promise 实例,就会先调用Promise.resolve方法,将参数转为 Promise 实例,再进一步处理。
// Promise.all([
// getDate(true),
// getName(),
// getDate(true)
// ]).then(res => {
// console.log(res)
// }).catch(err => {
// console.log(err) // error
// })
Promise.all([
getDate(true),
getDate(true),
getDate(true)
]).then(res => {
console.log(res) // ['成功', '成功', '成功']
}).catch(err => {
console.log(err)
})
3.Promise.race([])
该方法用于将多个 Promise 实例,包装成一个新的 Promise 实例;
[] 里面的内容都会触发;
只要[]之中有一个实例率先改变状态,p的状态就跟着改变;
function getDate(val) {
returnnew Promise((resolve, reject) => {
if (val) {
setTimeout(() => {
console.log('我执行了')
resolve(val)
}, 200)
} else {
reject('error')
}
})
}
function getName() {
return 'Martin'
}
function getError() {
return Promise.reject('报错了')
}
// Promise.race([
// getDate('001'),
// getDate('002')
// ]).then(res => {
// console.log(res) // 001
// })
// getDate()会被调用两次
Promise.race([
getDate('001'),
getDate('002'),
getName()
]).then(res => {
console.log(res) // Martin
}).then(res => {
// []之中有一个实例率先改变状态,后续不在执行
console.log(res, 'res2==') // undefined
})
// Promise.race([
// getDate('001'),
// getError(),
// getName(),
// ]).then(res => {
// console.log(res)
// }).catch(err => {
// console.log(err) // 报错了
// })
4. Promise.allSettled([])
该方法用于将多个 Promise 实例,包装成一个新的 Promise 实例;
只有等到所有这些参数实例都返回结果,一旦结束,状态总是fulfilled,不会变成rejected。
function getDate(val) {
returnnew Promise((resolve, reject) => {
if (val) {
setTimeout(() => {
console.log('我执行了')
resolve(val)
}, 200)
} else {
reject('error')
}
})
}
function getName() {
return 'Martin'
}
function getError() {
return Promise.reject('报错了')
}
Promise.allSettled([
getDate('001'),
getName(),
getError()
]).then(res => {
console.log(res, 'then') // 执行
}).catch(err => {
console.log(err, 'catch') // 不会执行
})
5. Promise.any([])
该方法用于将多个 Promise 实例,包装成一个新的 Promise 实例
Promise.any()和Primise.reca()方法很像,不同点在于不会因为某个Promise变成rejected状态而【结束】
只要参数实例有一个变成fulfilled状态,包装实例就会变成fulfilled状态;
如果所有参数实例都变成rejected状态,包装实例就会变成rejected状态。
function getDate(val) {
return new Promise((resolve, reject) => {
if (val) {
setTimeout(() => {
resolve(val)
}, 200)
} else {
reject('error')
}
})
}
function getName() {
return 'Martin'
}
function getError(val=1) {
return Promise.reject(val, '报错了')
}
// 当其中有fulfilled状态,不在进入catch();谁先执行饭返回谁的fulfilled;反之执行catch,返回报错信息
// Promise.any([
// getError(),
// getDate('001'),
// getName(),
// ]).then(res => {
// console.log(res) // Martin
// }).catch(err => {
// console.log(err)
// })
Promise.any([
getError('001'),
getError('002')
]).then(res => {
console.log(res)
}).catch(err => {
console.log(err) // AggregateError: All promises were rejected
})
6. 异步加载图片例子
function loadImg(src) {
returnnew Promise((resolve, reject) => {
// let img = document.createElement('img')
const img = new Image();
img.src = src
img.onload = function() {
resolve(img)
}
img.onerror = function(err) {
reject(err)
}
})
}
function showImgs(imgs) {
imgs.forEach(img => {
document.body.appendChild(img)
})
}
Promise.all([
loadImg('https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=842749842,2379754481&fm=26&gp=0.jpg'),
loadImg('https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=842749842,2379754481&fm=26&gp=0.jpg'),
loadImg('https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=842749842,2379754481&fm=26&gp=0.jpg')
]).then(res => {
showImgs(res)
})