剖析ES6的Promise对象
程序员文章站
2022-07-13 09:19:47
...
Promise出现的原因
传统解决异步操作的时候是采用使用回调函数的方式,并且当存在多个异步操作需要处理时,需要多次嵌套回调就会产生callback hell,且代码的可读性不高。Promise能够很好的解决这些问题。
Promise对象的状态
Promise 对象有三种状态:
- Fulfilled 可以理解为成功的状态
- Rejected 可以理解为失败的状态
- Pending 既不是 Fulfilld 也不是 Rejected 的状态,可以理解为 Promise 对象实例创建时候的初始状态
使用resolve将Promise的状态转变为成功状态;使用reject将Promise的状态转变为失败状态。
Promise简单使用
let ajax = fucntioon (flg) {
return new Promise(function (resolve,reject) {
if (flg) {
resolve('Hello'); // 将Promise的状态转变为成功状态
} else {
reject('Error'); // 将Promise的状态转变为失败状态
}
})
}
// 执行函数返回一个Promise对象
//当对象状态转变为成功状态的时候调用then()中的第一个函数,此时的参数即为resolve()传的参数
//当对象状态转变为失败状态的时候调用then()中的第二个函数,此时的参数即为reject()传的参数
ajax(true).then(function (msg) {
alert(msg);
}, function (msg) {
alert(msg);
})
其中的 .then(fn,fn) 可以换一种写法 使用catch如下:
ajax(true).then(function (msg) {
alert(msg);
}).catch(function (msg) {
alert(msg);
})
即 .then(fn1,fn2) 等价于 .then(fn1).catch(fn2)。
我们还可以连续使用then,每一次执行该方法时总是会返回一个 Promise 对象,在 then()参数函数中的返回值,可以作为后续操作的参数。
ajax(true).then(function (message) {
return message;
}).then(function (message) {
return message + ' World';
}).then(function (message) {
return message + '!';
}).then(function (message) {
alert(message);
}); // Hello World !
Promise.all和Promise.race
- Promise.all([pro1,pro2...]).then(fn) —— 可以接收一个 Promise 对象的数组作为参数,当这个数组里面所有的 Promise 对象都变为成功状态时,才会执行then中的函数fn
- Promise.race([pro1,pro2...]).then(fn) —— 可以接收一个 Promise 对象的数组作为参数,一旦这个数组里面有一个 Promise 对象变为成功状态时,就执行then中的函数fn,之后就不再关心数组中剩余的Promise对象状态的改变,即剩余Promise 对象状态改变时不会触发fn函数的调用。
举例说明:
Promise.all([pro1,pro2...]).then(fn) 的使用:当请求的所有图片加载完之后才在页面显示出来。
{
// 所有图片加载完再添加到页面
function loadImg(src){
return new Promise((resolve,reject)=>{
let img=document.createElement('img');
img.src=src;
img.onload=function(){
resolve(img);
}
img.onerror=function(err){
reject(err);
}
})
}
function showImgs(imgs){
imgs.forEach(function(img){
document.body.appendChild(img);
})
}
// .all 把所有的Promise实例当做一个处理
// 当所有的Promise对象状态都变为成功状态后才执行下一步then
Promise.all([
loadImg('./img1.jpg'),
loadImg('./img2.jpg'),
loadImg('./img3.jpg')
]).then(showImgs)
}
Promise.race([pro1,pro2...]).then(fn)的使用:当请求图片中的一个加载完之后就显示在页面上。
{
// 有一个图片加载完就添加到页面
function loadImg(src){
return new Promise((resolve,reject)=>{
let img=document.createElement('img');
img.src=src;
img.onload=function(){
resolve(img);
}
img.onerror=function(err){
reject(err);
}
})
}
function showImgs(img){
let p=document.createElement('p');
p.appendChild(img);
document.body.appendChild(p)
}
// .race 指多个状态中有一个状态率先改变时,race实例就跟着改变(即进行下一步调用then方法或者其他),之后的就不响应不理会了
Promise.race([
loadImg('./img1.jpg'),
loadImg('./img2.jpg'),
loadImg('./img3.jpg')
]).then(showImgs)
}
Promise浏览器兼容现状
在项目中使用Promsie对象,可以使用第三方插件bluebird.js ( github地址:https://github.com/petkaantonov/bluebird )
上一篇: JavaScript实现海报二维码生成+下载自定义名称[精选]
下一篇: 自定义控件+二维码