本文概述
一个promise表示异步操作的最终结果。与承诺互动的主要方式是通过then方法, 该方法注册回调以接收承诺的最终值或承诺无法实现的原因。在某些情况下, 你可能需要检查承诺的状态。你可能首先要做的是检查Promise对象是否具有提供此信息的某些属性, 但令你惊讶的是, 没有。
如果在控制台中转储承诺, 你将看到它将显示2个”属性” PromiseStatus和PromiseValue:
但是, 如果尝试使用Javascript访问这些属性, 则会看到这些值是未定义的。
解决方法
与Promises API的原始规范一样, 没有访问诺言内部状态的标准方法, 你仍然可以通过创建一个非常简单的包装程序来解决此问题, 该包装程序将修改Promise并添加一些有用的方法。
以下包装器是基于Stack Overflow中此问题的答案。该函数期望需要修改的promise, 然后它将使用3个额外的方法isPending, isRejected和isFulfilled返回修改后的promise。在开始使用此变通办法之前, 我们想以一种简单的方式向你解释承诺的所有状态的概念。一个承诺必须处于以下三种状态之一:
已完成
兑现了承诺的状态。这意味着承诺已被解决, 并且现在具有其解决的价值(使用内部解决功能)。承诺所代表的操作已成功完成。
被拒绝
拒绝表示承诺已被拒绝, 现在有其被拒绝的原因(使用内部拒绝功能)。由promise表示的操作无法获取值, 因此有一个无法获取值的原因(通常是错误代码或错误对象, 但可以是任何东西)。
待定
待定是初始的承诺状态。承诺所代表的操作尚未实现或拒绝。
知道了, 让我们开始吧:
/**
* This function allow you to modify a JS Promise by adding some status properties.
* Based on: http://stackoverflow.com/questions/21485545/is-there-a-way-to-tell-if-an-es6-promise-is-fulfilled-rejected-resolved
* But modified according to the specs of promises : https://promisesaplus.com/
*/
function MakeQuerablePromise(promise) {
// Don't modify any promise that has been already modified.
if (promise.isResolved) return promise;
// Set initial state
var isPending = true;
var isRejected = false;
var isFulfilled = false;
// Observe the promise, saving the fulfillment in a closure scope.
var result = promise.then(
function(v) {
isFulfilled = true;
isPending = false;
return v;
}, function(e) {
isRejected = true;
isPending = false;
throw e;
}
);
result.isFulfilled = function() { return isFulfilled; };
result.isPending = function() { return isPending; };
result.isRejected = function() { return isRejected; };
return result;
}
请记住, 该方法返回作为第一个参数提供但已修改的promise。
用法
要了解MakeQuerablePromise方法的工作原理, 请分析以下示例:
// Your promise won't cast the .then function but the returned by MakeQuerablePromise
var originalPromise = new Promise(function(resolve, reject){
setTimeout(function(){
resolve("Yeah !");
}, 10000);
});
var myPromise = MakeQuerablePromise(originalPromise);
console.log("Initial fulfilled:", myPromise.isFulfilled());//false
console.log("Initial rejected:", myPromise.isRejected());//false
console.log("Initial pending:", myPromise.isPending());//true
myPromise.then(function(data){
console.log(data); // "Yeah !"
console.log("Final fulfilled:", myPromise.isFulfilled());//true
console.log("Final rejected:", myPromise.isRejected());//false
console.log("Final pending:", myPromise.isPending());//false
});
如果你不想为原始的诺言创建额外的变量, 那么直接将诺言作为第一个参数提供:
var myPromise = MakeQuerablePromise(new Promise(function(resolve, reject){
setTimeout(function(){
resolve("Yeah !");
}, 10000);
}));
console.log("Initial fulfilled:", myPromise.isFulfilled());
console.log("Initial rejected:", myPromise.isRejected());
console.log("Initial pending:", myPromise.isPending());
myPromise.then(function(data){
console.log(data); // "Yeah !"
console.log("Final fulfilled:", myPromise.isFulfilled());
console.log("Final rejected:", myPromise.isRejected());
console.log("Final pending:", myPromise.isPending());
});
根据承诺的状态, 函数返回的值将有所不同, 并且你执行Promise的回调时不会看到任何更改。
编码愉快!
评论前必须登录!
注册