当我还是一个小白的时候,我翻了很多对于Promise介绍的文档,我始终没能了解所谓解决异步操作的痛点是什么意思
直到我翻了谷歌第一页的所有中文文档我才有所顿悟,其实从他的英文字面意思了解最为简略粗犷
这就是一个承诺,相当于在代码中提供一个在任何时候承诺之后要做什么事的形式,这个承诺可能会兑现也可能无奈兑现,当然也可能在兑现的过程中
用这个来代替咱们已经须要写的回调函数,能够防止JavaScript程序中的回调天堂
所以先不去学习的语法,从另一个形式先了解,心愿能够帮忙你更好的学习或上手Promise
什么是Promise?
Promise是异步编程的一种解决方案,能够代替传统的解决方案,比方回调函数和事件
其在ES6中对立了用法,并提供了原生的Promise对象,Promise对象示意异步操作的最终实现(或失败)及其后果值
作为对象,Promise有以下两个特点:
-
对象的状态不受外界影响
- 只有异步操作的后果,能够决定以后是哪一种状态,任何其余操作都无奈扭转这个状态,
这也是Promise这个名字的由来,它的英语意思就是承诺,示意其余伎俩无奈扭转
- 只有异步操作的后果,能够决定以后是哪一种状态,任何其余操作都无奈扭转这个状态,
-
一旦状态扭转了就不会在变,也就是说任何时候Promise都只有一种状态
pending:初始状态,不是胜利或失败状态;fulfilled(resolved):操作胜利实现状态;rejected:操作失败状态Promise对象的状态扭转,只有两种可能:从Pending变为Resolved和从Pending变为Rejected,
只有这两种状况产生,状态就凝固了,不会再变了,会始终放弃这个后果,
就算扭转曾经产生了,你再对Promise对象增加回调函数,也会立刻失去这个后果,
这与事件(Event)齐全不同,事件的特点是,如果你错过了它,再去监听,是得不到后果的
Promise的创立和用处
- 构造函数承受一个名为
executor的函数,此执行函数承受两个f函数参数,resolve和reject。
new Promise( /* executor */ function(resolve, reject { ... }) );
- Promise通常用于阻塞代码和异步操作,其中包含文件调用,API调用,DB调用,IO调用等等
- 这些异步操作的启动产生在执行函数中,如果异步操作胜利,则通过
promise的创建者调用resolve()函数返回预期后果,
同样,如果出现意外谬误,则通过调用reject()函数传递谬误具体信息 - 因为
promise会立刻执行,咱们无奈查看promise的初始状态,所以创立一个须要工夫执行的promise最简略的形式就是
应用setTimeOut()函数,通过浏览器控制台的输入能够直观看到之前所说的状态,以及他的变动过程
var promiseFir = new Promise(function(resolve, reject) {
setTimeout(function() {
resolve({
message: '与大家分享常识很开心!',
code: 200
});
}, 2000)
})
console.log(promiseFir);
setTimeout(function() {
console.log(promiseFir);
}, 2000)
Promise的办法
-
3种原型办法
- Promise.prototype.then(onFulfilled, onRejected) 链式操作
- Promise.prototype.catch(onRejected) 捕获谬误
- Promise.prototype.finally(onFinally) 最终操作
- 上面用一个小示例简略疾速理解下这三个原型办法的用法
// 用一个小故事举例,你是一个上学的孩子,你问你的妈妈要一个电话。她说: 这个月底我要买一部手机
var momsPromise = new Promise(function(resolve, reject) {
momsSavings = 20000; // 因为妈妈没有足够储蓄所以无奈买到礼物
// momsSavings = 200000; // 如果妈妈有足够的储蓄就能够买到礼物
priceOfPhone = 60000;
if (momsSavings > priceOfPhone) {
resolve({
brand: "iphone",
model: "6s"
});
} else {
reject("咱们没有足够的储蓄,让咱们多存点钱吧。");
}
});
momsPromise.then(function(value) {
console.log("哇,我失去这个电话作为礼物 ", JSON.stringify(value));
});
momsPromise.catch(function(reason) {
console.log("妈妈不能给我买电话,因为 ", reason);
});
momsPromise.finally(function() {
console.log(
"不论妈妈能不能给我买个电话,我依然爱她"
);
});
-
4种静态方法
- Promise.resolve()
- Promise.reject()
- Promise.all()
- Promise.race()
<span id=”jumpId-then”></span>
Promise.prototype.then(onFulfilled, onRejected) 链式操作
Promise.prototype.then()办法返回的是一个新的Promise对象,因而能够采纳链式写法Promise.prototype.then()办法带有以下三个参数:胜利回调,失败回调,后退回调,个别状况下只须要实现第一个,前面是可选的
function ptFir() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log('办法1执行');
resolve('办法1执行结束');
}, 2000)
})
}
function ptSec() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log('办法2执行');
resolve('办法2执行结束');
}, 1000)
})
}
function ptThi() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log('办法3执行');
resolve('办法3执行结束');
}, 3000)
})
}
ptFir().then(function(data) {
console.log('第一个回调:' + data);
return ptSec();
}).then(function(data) {
console.log('第二个回调:' + data);
return ptThi();
}).then(function(data) {
console.log('第三个回调:' + data);
return '还没完?该完结了吧!';
}).then(function(data) {
console.log(data);
})
<span id=”jumpId-catch”></span>
Promise.prototype.catch(onRejected) 捕获谬误
Promise.prototype.catch()办法是Promise.prototype.then(null, rejection)的别名,用于指定产生谬误时的回调函数Promise对象的谬误具备“冒泡”性质,会始终向后传递,直到被捕捉为止,也就是说,谬误总是会被下一个catch语句捕捉
promise().then(function(data) {
// todo something
}).catch(function(err) {
// 解决上个回调函数的谬误
})
<span id=”jumpId-finally”></span>
Promise.prototype.finally(onFinally) 最终操作
不论promise对象最初的状态,在执行完.then或catch指定的回调函数当前,都会执行finally办法指定的回调函数
promise().then(function(data) {
// todo something
}).catch(function(err) {
// 解决上个回调函数的谬误
}).finally(function(result) {
// 解决then/catch之后必须执行的操作
})
<span id=”jumpId-resolve-reject”></span>
Promise.resolve() / Promise.reject()
- 这两个是帮忙办法或快捷方式,它们能够帮忙您轻松创立
resolve和reject办法 - 须要留神的是:如果
Promise.resolve()办法的参数,
不是具备.then()办法的对象(又称thenable对象),则返回一个新的Promise对象,且它的状态为fulfilled;
如果Promise.resolve办法的参数是一个Promise对象的实例,则会被一成不变地返回 Promise.reject()办法同上
var promise = Promise.resolve('Hello,这里是执行胜利的内容!');
// var promise = Promise.reject('出错了,这里是被发现的谬误!'); // 胜利和失败只会有一种状态哦
promise.then(function(data) {
console.log(data)
});
promise.catch(function(err) {
console.log(err)
});
<span id=”jumpId-all”></span>
Promise.all()
- 当你解决多个
promise时,最好先创立一个promise数组,而后对这些promise集执行必要的操作 Promise.all(iterable) 办法返回一个Promise实例,此实例在iterable参数内所有的promise- 都实现(resolved)或参数中不蕴含
promise时回调实现(resolve) - 如果参数中
promise有一个失败(rejected),此实例回调失败(reject),失败起因的是第一个失败promise的后果 - 留神!!!这里的异步操作是并行执行的,等到它们都执行完后才会进到
then()外面,
并且all()办法会把所有异步操作的后果放进一个数组中传给then() -
上面的示例须要阐明的内容
- 只有3个办法的状态都变成
fulfilled,p的状态才会变成fulfilled,此时3个办法的返回值组成一个数组,传递给p的回调函数 - 只有3个办法之中有一个被
rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数
- 只有3个办法的状态都变成
function ptFir() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log('办法1执行');
resolve('办法1执行结束');
}, 2000)
})
}
function ptSec() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log('办法2执行');
resolve('办法2执行结束');
}, 1000)
})
}
function ptThi() {
return new Promise(function(resolve, reject) {
setTimeout(function() {
console.log('办法3执行');
resolve('办法3执行结束');
}, 3000)
})
}
Promise.all([ptFir(), ptSec(), ptThi()]).then(function(data) {
console.log(data);
console.log({}.toString.call(data));
})
<span id=”jumpId-race”></span>
Promise.race()
Promise.race(iterable)办法返回一个promise,一旦迭代器中的某个promise解决或回绝,返回的promise就会解决或回绝all()办法的成果实际上是「谁跑的慢,以谁为准执行回调」 ,
那么绝对的就有另一个办法「谁跑的快,以谁为准执行回调」,这就是race()办法,这个词原本就是赛跑的意思- 这个
race()办法有什么用呢?应用场景还是很多的,比方咱们能够用race()给某个异步申请设置超时工夫,
并且在超时后执行相应的操作
// ptFir(), ptSec(), ptThi() 同上
Promise.all([ptFir(), ptSec(), ptThi()]).then(function(data) {
console.log(data);
console.log({}.toString.call(data));
})
应用Promise的一些教训法令
- 进行异步操作或应用阻塞代码时,请应用
Promise - 为了代码的可读性,
resolve()办法看待.then(),reject()办法对应.catch() - 确保同时写入
.catch()和.then()办法来实现所有的promise - 如果在这两种状况下都须要做一些事件,请应用
.finally() - 咱们只有一次扭转每个
promise (繁多准则) - 咱们能够在一个
promise中增加多个处理程序 Promise对象中所有办法的返回类型,无论是静态方法还是原型办法,都是Promise- 在
all()办法中,无论哪个promise首先未实现,promise的程序都放弃在值变量中
参考文档一 ———— 彻底了解Javascript 中的 Promise
参考文档二 ———— 艰深通俗的了解Promise中的then
参考文档三 ———— 了解 Javascript 中的 Promise
参考文档四 ———— JavaScript Promise 对象
发表回复