Get state of Angular deferred?

前端 未结 4 1824
野的像风
野的像风 2020-12-04 19:41

With jQuery deferreds I\'m used to be able to check the current state like this:

var defer = $.Deferred();
defer.state();  //Returns the state of the deferre         


        
4条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-12-04 20:06

    Updated:

    Unfortunately this doesn't looks like its possible with $q. You'll have to put this code inside your then method.

    myPromise()
    .then(function() {
        // everything in here resolved
    },
    function() {
        // everything in here rejected
    },
    function() {
        // everything in here pending (with progress back)
    });
    

    Other:

    This is for the Q library not angular's $q but similar.

    Angular is inspired by the Q library, check out the source, its actually not that scary. https://github.com/kriskowal/q/blob/v1/q.js

    You can use myPromise.inspect().state there are ['pending', 'rejected', 'fulfilled']

    You also have:

    myPromise.isFulfilled();
    myPromise.isPending();
    myPromise.isRejected();
    

    Check out this JSfiddle and open the console for logged results. http://jsfiddle.net/S6LzP/

    More granular, Looking at the defer function on line 488:

    function defer() {
        // if "messages" is an "Array", that indicates that the promise has not yet
        // been resolved.  If it is "undefined", it has been resolved.  Each
        // element of the messages array is itself an array of complete arguments to
        // forward to the resolved promise.  We coerce the resolution value to a
        // promise using the `resolve` function because it handles both fully
        // non-thenable values and other thenables gracefully.
        var messages = [], progressListeners = [], resolvedPromise;
    
        var deferred = object_create(defer.prototype);
        var promise = object_create(Promise.prototype);
    
        promise.promiseDispatch = function (resolve, op, operands) {
            var args = array_slice(arguments);
            if (messages) {
                messages.push(args);
                if (op === "when" && operands[1]) { // progress operand
                    progressListeners.push(operands[1]);
                }
            } else {
                nextTick(function () {
                    resolvedPromise.promiseDispatch.apply(resolvedPromise, args);
                });
            }
        };
    
        // XXX deprecated
        promise.valueOf = function () {
            if (messages) {
                return promise;
            }
            var nearerValue = nearer(resolvedPromise);
            if (isPromise(nearerValue)) {
                resolvedPromise = nearerValue; // shorten chain
            }
            return nearerValue;
        };
    
        promise.inspect = function () {
            if (!resolvedPromise) {
                return { state: "pending" };
            }
            return resolvedPromise.inspect();
        };
    
        if (Q.longStackSupport && hasStacks) {
            try {
                throw new Error();
            } catch (e) {
                // NOTE: don't try to use `Error.captureStackTrace` or transfer the
                // accessor around; that causes memory leaks as per GH-111. Just
                // reify the stack trace as a string ASAP.
                //
                // At the same time, cut off the first line; it's always just
                // "[object Promise]\n", as per the `toString`.
                promise.stack = e.stack.substring(e.stack.indexOf("\n") + 1);
            }
        }
    
        // NOTE: we do the checks for `resolvedPromise` in each method, instead of
        // consolidating them into `become`, since otherwise we'd create new
        // promises with the lines `become(whatever(value))`. See e.g. GH-252.
    
        function become(newPromise) {
            resolvedPromise = newPromise;
            promise.source = newPromise;
    
            array_reduce(messages, function (undefined, message) {
                nextTick(function () {
                    newPromise.promiseDispatch.apply(newPromise, message);
                });
            }, void 0);
    
            messages = void 0;
            progressListeners = void 0;
        }
    
        deferred.promise = promise;
        deferred.resolve = function (value) {
            if (resolvedPromise) {
                return;
            }
    
            become(Q(value));
        };
    
        deferred.fulfill = function (value) {
            if (resolvedPromise) {
                return;
            }
    
            become(fulfill(value));
        };
        deferred.reject = function (reason) {
            if (resolvedPromise) {
                return;
            }
    
            become(reject(reason));
        };
        deferred.notify = function (progress) {
            if (resolvedPromise) {
                return;
            }
    
            array_reduce(progressListeners, function (undefined, progressListener) {
                nextTick(function () {
                    progressListener(progress);
                });
            }, void 0);
        };
    
        return deferred;
    }
    

    Mostly notably the method at the very bottom deferred.notify.

    Example usage:

    function requestOkText(url) {
        var request = new XMLHttpRequest();
        var deferred = Q.defer();
    
        request.open("GET", url, true);
        request.onload = onload;
        request.onerror = onerror;
        request.onprogress = onprogress;
        request.send();
    
        function onload() {
            if (request.status === 200) {
                deferred.resolve(request.responseText);
            } else {
                deferred.reject(new Error("Status code was " + request.status));
            }
        }
    
        function onerror() {
            deferred.reject(new Error("Can't XHR " + JSON.stringify(url)));
        }
    
        function onprogress(event) {
            deferred.notify(event.loaded / event.total);
        }
    
        return deferred.promise;
    }
    
    requestOkText("http://localhost:3000")
    .then(function (responseText) {
        // If the HTTP response returns 200 OK, log the response text.
        console.log(responseText);
    }, function (error) {
        // If there's an error or a non-200 status code, log the error.
        console.error(error);
    }, function (progress) {
        // Log the progress as it comes in.
        console.log("Request progress: " + Math.round(progress * 100) + "%");
    });
    

提交回复
热议问题