Promise的3个状态
Promise
中有一个 [[PromiseState]]
内部属性,用于表示 Promise
的三种状态:
- Pending 此时操作尚未完成,表示处于进行中的状态。
- Fulfilled 此时操作已经完成,表示处于操作成功中的状态。
- Rejected 此时操作已经完成,表示处于操作失败中的状态。
Promise
的状态改变只有两种情况,一旦操作完成不可逆:
- Pending ————> Fulfilled
- Pending ————> Rejected
它不会暴露在 Promise
对象上,所以不能以编程的方式检测出其状态,只有当 Promise
状态改变的时候,会触发特定的方法。
Promise的2个方法
then()
当 Promise
的状态改变的时候,也就是从 Pending
状态变成 Fulfilled
或者 Rejected
状态的时候,会调用 then()
方法。它接收两个可选参数:
- 当
Promise
的状态变为fullfilled
时调用的完成函数 - 当
Promise
的状态变为rejected
时调用的拒绝函数。
promise.then(
function(contents) {...},
function(err) {...},
)
如果一个对象实现了上述的
then()
方法,就可以称为thenable
对象,Promise
是thenable
对象的一个子集。
可以传入两个参数,表示完成函数和拒绝函数;也可以传入一个参数,表示完成函数;如果只想要拒绝函数,需要将第一个参数置为 null
,这样使用有点奇怪,所以提供了一个专门处理操作失败的方法。
catch()
catch()
相当于只给其传入拒接处理程序的 then()
方法。
promise.catch(
function(err) {...}
)
创建未完成的 Promise
Promise 构造函数
new Promise(executor)
构造函数创建新的 promise
,接收一个执行器参数, 。执行器又接收两个参数,resolve
函数和 reject
函数。执行器成功完成调用 resolve
函数,失败调用 reject
函数。
resolve
函数会将 Promise
的状态变成 fullfilled
,reject
函数会将 Promise
的状态变成 rejected
。
let i = 12;
let promise = new Promise(function(resolve,reject){
if(i<10){ reject('i不能小于10'); return; }
resolve(i);
});
console.log(promise);
promise.then((value) => {
console.log(value)
}, (err) => {
console.log(err)
})
这样使用创建出来的是一个 fullfilled
状态的 promise
,所以会直接触发 then()
方法并执行完成函数。如果 i<10
,会创建一个 rejected
状态的 promise
,则会直接触发 then()
方法并执行失败函数。
未完成的 Promise
需要将 resolve
函数和 reject
函数放到回调函数中处理,也就是异步处理。
var fs = require("fs")
function readFile(filename) {
return new Promise( (resolve, reject) => {
fs.readFile(filename, {encoding: "utf8"}, (err, contents) => {
// 回调函数,会扔到异步任务队列中
if (err) { reject(err); return; }
resolve(contents);
});
});
}
let promise = readFile("../example1.txt");
console.log(promise); // pending状态
promise.then(
(contents) => {
console.log(contents);
console.log(promise); //fulfilled状态
},
(err) => {
console.error(err.message);
console.log(promise); //rejected状态
});
创建已完成的 Promise
创建一个未完成的 Promise
,最好使用 Promise
构造函数。但是使用构造函数创建一个已完成的 Promise
,就想上两个例子,就显得没有什么意义。
Promise.resolve()
只接收一个参数:
- 参数为基础类型或普通对象,返回
fullfilled
状态的Promise
- 参数为
Promise
,直接返回传入的Promise
- 参数为
Thenable
对象,会将这个Thenable
对象转换为Promise
,并执行Thenable
对象的then()
方法。
var fs = require("fs")
function readFile(filename) {
return new Promise((resolve, reject) => {
fs.readFile(filename, {encoding: "utf8"}, (err, contents) => {
if (err) { reject(err);return; }
resolve(contents);
});
});
}
//1.参数为非thenable对象或非对象或不传参,返回fulfilled状态的promise
let promise = Promise.resolve();
let promise1 = Promise.resolve(42);
//2.参数为promise实例,原封不动的返回传入的promise
let pending = readFile("../example.txt"); // pending状态
let promiseP1 = Promise.resolve(pending);
//3.参数为thenable实例,返回fulfilled状态的promise
let thenable = {
then: function (resolve, reject) {
resolve(42);
}
};
let p1 = Promise.resolve(thenable);
Promise.reject()
只接收一个参数,参数为基础类型或普通对象,返回 rejected
状态的 Promise
。其他情况和 Promise.resolve()
一致。
执行器错误
如果在执行器中抛出一个错误,其实默认内部会使用 try-catch
,捕获到错误后执行 reject()
方法。
let promise = new Promise(function(resolve,reject){
throw new Error('Explosion!')
});
// 相当于
let promise = new Promise(function(resolve,reject){
try {
throw new Error('Explosion!')
} catch (ex) {
reject(ex)
}
});