View all pending promises in javascript

后端 未结 2 357
孤街浪徒
孤街浪徒 2020-12-11 11:04

In my tests, sometimes I get timeouts, and it would be very useful to see what where the promises that were pending before the timeout, so that I know what promises have the

相关标签:
2条回答
  • 2020-12-11 11:17

    A promise chain is designed progressively to deliver values down its success path or a "reason" down its error path. It is not designed to be enquired at some arbitrary point in time for a "snapshot" the state of individual promises that are assimilated by it.

    Therefore, a promise chain offers no "natural" way to do what you ask.

    You need to contrive a mechanism for :

    • registering promises of interest.
    • tracking each registered promise's state (if not already provided by the promise implementation).
    • retreiving, on demand, the registered promises, filtered by state.

    A constructor along these lines will do the job :

    function Inspector() {
        var arr = [];
        this.add = function(p, label) {
            p.label = label || '';
            if(!p.state) {
                p.state = 'pending';
                p.then(
                    function(val) { p.state = 'resolved'; },
                    function(e) { p.state = 'rejected'; }
                );
            }
            arr.push(p);
            return p;
        };
        this.getPending  = function() {
            return arr.filter(function(p) { return p.state === 'pending'; });
        };
        this.getSettled = function() {
            return arr.filter(function(p) { return p.state !== 'pending'; });
        };
        this.getResolved = function() {
            return arr.filter(function(p) { return p.state === 'resolved'; });
        };
        this.getRejected = function() {
            return arr.filter(function(p) { return p.state === 'rejected'; });
        };
        this.getAll  = function() {
            return arr.slice(0); // return a copy of arr, not arr itself.
        };
    };
    

    The only methods required by the question are .add() and .getPending(). The others are provided for completeness.

    You can now write :

    var inspector = new Inspector();
    
    Promise.resolve().then(function() {
        console.log(1);
    }).then(function() {
        var p = new Promise(function(resolve, reject) {
            // NEVER RESOLVING PROMISE
            console.log(2);
        });
        return inspector.add(p, '2');
    }).then(function() {
        // function that will never be called
        console.log(3);
    });
    
    setTimeout(function() {
        const pendingPromises = inspector.getPending();
        console.log(pendingPromises);
        process.exit();
    }, 5000);
    

    fiddle

    The use of Inspector isn't confined to promises assimilated by promise chains. It could be used for any arbitrary set of promises, for example a set to be aggregated with Promise.all() :

    promise_1 = ...;
    promise_2 = ...;
    promise_3 = ...;
    
    var inspector = new Inspector();
    inspector.add(promise_1, 'promise 1');
    inspector.add(promise_2, 'promise 2');
    inspector.add(promise_3, 'promise 3');
    
    var start = Date.now();
    var intervalRef = setInterval(function() {
        console.log(Date.now() - start + ': ' + inspector.getSettled().length + ' of ' + inspector.getAll().length + ' promises have settled');
    }, 50);
    
    Promise.all(inspector.getAll()).then(successHandler).catch(errorHandler).finally(function() {
        clearInterval(intervalRef);
    });
    
    0 讨论(0)
  • I suggest using library such as Bluebird that is ~6x times faster than native promises, offers useful warnings and additional useful methods like - timeout which might help you with this issue.

    0 讨论(0)
提交回复
热议问题