最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

View all pending promises in javascript - Stack Overflow

programmeradmin1浏览0评论

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 most chances of being in an "always pending state".

Is there a way to do that ?

Here's an example code :

Promise.resolve().then(function firstFunction() {
    console.log(1);
    return 1;
}).then(function () {
    return new Promise(function secondFunction(resolve, reject) {
        // NEVER RESOLVING PROMISE
        console.log(2);
    });
}).then(function thirdFunction() {
    // function that will never be called
    console.log(3);
})

setTimeout(function timeoutTest() {
    const pendingPromises = [];// ??????????? how do I get the pendingPromises
    console.log(pendingPromises);
    process.exit();
}, 5000);

I would like, if possible, to get in pendingPromises the name of the function and stacktrace of the promise secondFunction, since it is the one that will never resolve.

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 most chances of being in an "always pending state".

Is there a way to do that ?

Here's an example code :

Promise.resolve().then(function firstFunction() {
    console.log(1);
    return 1;
}).then(function () {
    return new Promise(function secondFunction(resolve, reject) {
        // NEVER RESOLVING PROMISE
        console.log(2);
    });
}).then(function thirdFunction() {
    // function that will never be called
    console.log(3);
})

setTimeout(function timeoutTest() {
    const pendingPromises = [];// ??????????? how do I get the pendingPromises
    console.log(pendingPromises);
    process.exit();
}, 5000);

I would like, if possible, to get in pendingPromises the name of the function and stacktrace of the promise secondFunction, since it is the one that will never resolve.

Share Improve this question asked Sep 1, 2016 at 14:04 edi9999edi9999 20.6k15 gold badges98 silver badges135 bronze badges 4
  • Exact duplicate of Monitoring pending async operations in Node.js promised environment? – Bergi Commented Sep 1, 2016 at 14:11
  • Wow.. you are terribly confused... There is no way to return the synchronous timeline once you get into the promises (AKA asynchronous timeline). – Redu Commented Sep 1, 2016 at 19:38
  • They could be some features around it, it just is like à timeline and all links are explicit. It could be possible to wrap promises so that you get this sort if information. – edi9999 Commented Sep 1, 2016 at 19:41
  • For example github./emberjs/ember-inspector/pull/76 – edi9999 Commented Sep 1, 2016 at 19:43
Add a ment  | 

2 Answers 2

Reset to default 6

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 pleteness.

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);
});

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)

  1. 暂无评论