1.什么是Promise?
Promise是抽象异步处理对象以及对其进行各种操作的组件。
2.三种类型
Constructor是其中一种:
Promise类似于 XMLHttpRequest,从构造函数 Promise 来创建一个新建新promise对象作为接口。
要想创建一个promise对象、可以使用new来调用Promise的构造器来进行实例化。
var promise = new Promise(function(resolve, reject) {
// 异步处理
// 处理结束后、调用resolve 或 reject
});
//可以使用then,catch实例化:
成功resolve():
promise.then(onFulfilled, onRejected)
失败reject()有两种写法,后者更直观:
promise.then(undefined, onRejected) == promise.catch(onRejected)
3.Promise创建和处理方法:
4.new Promise()
方法的快捷方式
静态方法Promise.resolve(value)
可以认为是 new Promise()
方法的快捷方式。
###比如 Promise.resolve(42); 可以认为是以下代码的语法糖。
new Promise(function(resolve){
resolve(42);
});
###方法 Promise.resolve(value); 的返回值也是一个promise对象,所以我们可以像下面那样接着对其返回值进行 .then 调用。
Promise.resolve(42).then(function(value){
console.log(value);
});
5.Promise方法链
aPromise.then(function taskA(value){
// task A
}).then(function taskB(vaue){
// task B
}).catch(function onRejected(error){
console.log(error);
});
function taskA() {
console.log("Task A");
}
function taskB() {
console.log("Task B");
}
function onRejected(error) {
console.log("Catch Error: A or B", error);
}
function finalTask() {
console.log("Final Task");
}
var promise = Promise.resolve();
promise
.then(taskA)
.then(taskB)
.catch(onRejected)
.then(finalTask);
image.png
6.不管是 then 还是 catch 方法调用,都返回了一个新的promise对象。
6.1 我们说过 .catch
也可以理解为 promise.then(undefined, onRejected)
。
then不能进行错误处理的onRejected
function throwError(value) {
// 抛出异常
throw new Error(value);
}
// <1> onRejected不会被调用
function badMain(onRejected) {
return Promise.resolve(42).then(throwError, onRejected);
}
// <2> 有异常发生时onRejected会被调用
function goodMain(onRejected) {
return Promise.resolve(42).then(throwError).catch(onRejected);
}
// 运行示例
badMain(function(){
console.log("BAD");
});
goodMain(function(){
console.log("GOOD");
});
在上面的代码中, badMain 是一个不太好的实现方式(但也不是说它有多坏), goodMain 则是一个能非常好的进行错误处理的版本。
为什么说 badMain 不好呢?,因为虽然我们在 .then 的第二个参数中指定了用来错误处理的函数,但实际上它却不能捕获第一个参数 onFulfilled 指定的函数(本例为 throwError )里面出现的错误。
也就是说,这时候即使 throwError 抛出了异常,onRejected 指定的函数也不会被调用(即不会输出"BAD"字样)。
与此相对的是, goodMain 的代码则遵循了 throwError→onRejected 的调用流程。 这时候 throwError 中出现异常的话,在会被方法链中的下一个方法,即 .catch 所捕获,进行相应的错误处理。
.then 方法中的onRejected参数所指定的回调函数,实际上针对的是其promise对象或者之前的promise对象,而不是针对 .then 方法里面指定的第一个参数,即onFulfilled所指向的对象,这也是 then 和 catch 表现不同的原因。
``
2.10.2. 总结
这里我们又学习到了如下一些内容。
-
使用
promise.then(onFulfilled, onRejected)
的话- 在
onFulfilled
中发生异常的话,在onRejected
中是捕获不到这个异常的。
- 在
-
在
promise.then(onFulfilled).catch(onRejected)
的情况下-
then
中产生的异常能在.catch
中捕获
-
-
- 需要分场合使用。
我们需要注意如果代码类似 badMain
那样的话,就可能出现程序不会按预期运行的情况,从而不能正确的进行错误处理。
7.使用 reject 会比使用 throw 安全
在 then 中使用reject的方法
8.then原理
在 then 中注册的回调函数可以通过 return 返回一个值,这个返回值会传给后面的 then 或 catch 中的回调函数。
而且return的返回值类型不光是简单的字面值,还可以是复杂的对象类型,比如promise对象等。
这时候,如果返回的是promise对象的话,那么根据这个promise对象的状态,在下一个 then 中注册的回调函数中的onFulfilled和onRejected的哪一个会被调用也是能确定的。
也许实际中我们可能不常使用 reject ,但是比起来不假思索的使用 throw 来说,使用 reject 的好处还是很多的。
var promise = Promise.resolve();
promise.then(function () {
var retPromise = new Promise(function (resolve, reject) {
// resolve or reject 的状态决定 onFulfilled or onRejected 的哪个方法会被调用
});
return retPromise;
}).then(onFulfilled, onRejected);
###后面的then调用哪个回调函数是由promise对象的状态来决定的
也就是说,这个 retPromise 对象状态为Rejected的时候,会调用后面then中的 onRejected 方法,这样就实现了即使在 then 中不使用 throw 也能进行reject处理了。
var onRejected = console.error.bind(console);
var promise = Promise.resolve();
promise.then(function () {
var retPromise = new Promise(function (resolve, reject) {
reject(new Error("this promise is rejected"));
});
return retPromise;
}).catch(onRejected);
//简写
var onRejected = console.error.bind(console);
var promise = Promise.resolve();
promise.then(function () {
return Promise.reject(new Error("this promise is rejected"));
}).catch(onRejected);
网友评论