个性化阅读
专注于IT技术分析

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

本文概述

一个promise表示异步操作的最终结果。与承诺互动的主要方式是通过then方法, 该方法注册回调以接收承诺的最终值或承诺无法实现的原因。在某些情况下, 你可能需要检查承诺的状态。你可能首先要做的是检查Promise对象是否具有提供此信息的某些属性, 但令你惊讶的是, 没有。

如果在控制台中转储承诺, 你将看到它将显示2个”属性” PromiseStatus和PromiseValue:

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 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的回调时不会看到任何更改。

编码愉快!

赞(0)
未经允许不得转载:srcmini » 如何检查JavaScript承诺是否已实现,拒绝或解决

评论 抢沙发

评论前必须登录!