Promise 是异步编程的一种解决方案,比传统的解决方案——回调函数和事件——更合理和更强大。它由社区最早提出和实现,ES6 将其写进了语言标准,统一了用法,原生提供了Promise对象。
场景说明
图片依次的加载
function(){
var img1 = document.createElement('img')
img1.onload = function () {
var img2 = document.createElement('img')
img2.onload = function(){
var img3 = document.createElement('img')
img3.onload = function(){
// ....
}
}
}
}
这就是所谓的回调地狱,很显然,逻辑稍微复杂一些项目就很难维护了
Promise 的三种状态
- pending-进行中,不会触发then 和 catch
- resolved-已完成,会触发后续的 then 回调函数
- rejected-已失败,会触发后续的 catch 回调函数
状态变化是不可逆的 (fulfilled不可能变为pending, rejected不可能变为pending状态)
then和catch改变状态
- then 正常返回resolved,里面有报错则会返回rejected
const p1 = Promise.resolve().then(() => {
return 100
})
console.log('p1', p1)
// resolve 触发后续的 then 回调
p1.then(() => {
console.log(123)
})
const p2 = Promise.resolve().then(() => {
throw new Error('then error')
})
// rejected 触发后续 catch 回调
console.log('p2', p2)
p1.then(() => {
console.log('456')
}).catch(err => {
console.error('error100', err)
})
- catch 正常返回resolved,里面有报错则会返回rejected
const p3 = Promise.reject('my error').catch(err => {
console.log(err)
})
console.log('p3', p3) // reject 里没有报错,状态为resolved 触发后续 then
p3.then(() => {
console.log(100)
})
const p4 = Promise.reject('my error').catch(err => {
throw new Error('catch error')
})
console.log('p3', p4) // 状态为rejected 触发后续 catch
p4.then(() => {
console.log(200)
}).catch(() => {
console.log('somef error')
})
Promise的基本用法
loadImg(src) => {
// new Promise实例,接受两个参数(resolve,reject)
const promise = new Promise((resolve, reject) => {
var img = document.createElement('img')
img.onload = () => {
resolve(img)
}
img.onerror = () => {
reject('图片加载失败')
}
img.src = src
})
return promise
}
var src = 'https://img.qiyuandi.com/images/5/jtproxavrz40gja1.jpg'
var result = loadImg(src)
result.then((img) => {
console.log('图片的宽度' + img.width)
}, () => {
console.log('failed')
})
// 运行结果图片的宽度117
Promise多个串联
loadImg(src) => {
// new Promise实例,接受两个参数(resolve,reject)
const promise = new Promise((resolve, reject) => {
var img = document.createElement('img')
img.onload = () => {
resolve(img)
}
img.onerror = () => {
reject('图片加载失败')
}
img.src = src
})
return promise
}
// 多个串联
const src1 = 'https://img.qiyuandi.com/images/5/jtproxavrz40gja1.jpg'
const result1 = loadImg(src1)
const src2 = 'https://ss0.baidu.com/73F1bjeh1BF3odCf/it/u=559043697,829837996&fm=85&s=816240A611420EFE36F52D900300E082'
const result2 = loadImg(src2)
result1.then((img1) => {
console.log('第一张图片')
return result2
}).then((img2) => {
console.log('第二张图片')
}).catch((ex) => {
// 统一处理异常
console.log(ex)
})
Promise.all() && Promise.race()
Promise.all方法用于将多个Promise实例,包装成一个新的Promise实例:
loadImg(src) => {
// new Promise实例,接受两个参数(resolve,reject)
const promise = new Promise((resolve, reject) => {
var img = document.createElement('img')
img.onload = () => {
resolve(img)
}
img.onerror = () => {
reject('图片加载失败')
}
img.src = src
})
return promise
}
const src1 = 'https://img.qiyuandi.com/images/5/jtproxavrz40gja1.jpg'
const result1 = loadImg(src1)
const src2 = 'https://ss0.baidu.com/73F1bjeh1BF3odCf/it/u=559043697,829837996&fm=85&s=816240A611420EFE36F52D900300E082'
const result2 = loadImg(src2)
// Promise.all 接收一个 promise 对象的数组
// 待全部完成之后,统一执行success
Promise.all([result1, result2]).then((datas) => {
// 接收到的datas 是一个数组,依次包含了多个promise返回的内容
console.log('all', datas[0])
console.log('all', datas[1])
})
// Promise.race 接受一个包含多个 promise对象的数组
// 只要有一个完成,就执行 success
Promise.race([result1, result2]).then((data) => {
// 接收到的datas 是一个数组,依次包含了多个promise返回的内容
console.log('race', data)
})
Promise.all方法接受一个数组作为参数,p1、p2、p3都是Promise对象的实例,如果不是,就会先调用下面讲到的Promise.resolve方法,将参数转为Promise实例,再进一步处理。
Promise.race方法的参数与Promise.all方法一样,如果不是 Promise 实例,就会先调用下面讲到的Promise.resolve方法,将参数转为 Promise 实例,
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!