如何检查JavaScript承诺是否已实现,拒绝或解决

本文概述

  • 解决方法
  • 用法
一个promise表示异步操作的最终结果。与承诺互动的主要方式是通过then方法, 该方法注册回调以接收承诺的最终值或承诺无法实现的原因。在某些情况下, 你可能需要检查承诺的状态。你可能首先要做的是检查Promise对象是否具有提供此信息的某些属性, 但令你惊讶的是, 没有。
如果在控制台中转储承诺, 你将看到它将显示2个” 属性” PromiseStatus和PromiseValue:
如何检查JavaScript承诺是否已实现,拒绝或解决

文章图片
【如何检查JavaScript承诺是否已实现,拒绝或解决】但是, 如果尝试使用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 statevar 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 MakeQuerablePromisevar originalPromise = new Promise(function(resolve, reject){setTimeout(function(){resolve("Yeah !"); }, 10000); }); var myPromise = MakeQuerablePromise(originalPromise); console.log("Initial fulfilled:", myPromise.isFulfilled()); //falseconsole.log("Initial rejected:", myPromise.isRejected()); //falseconsole.log("Initial pending:", myPromise.isPending()); //truemyPromise.then(function(data){console.log(data); // "Yeah !"console.log("Final fulfilled:", myPromise.isFulfilled()); //trueconsole.log("Final rejected:", myPromise.isRejected()); //falseconsole.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的回调时不会看到任何更改。
编码愉快!

    推荐阅读