zloirock / core-js

Standard Library

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Nested setTimeout calls cause invalid Promise unhandled rejection message

loganfsmyth opened this issue · comments

Came across this when upgrading to Babel 5, picking up core-js 0.9.18, causing us to switch from Chrome promises to polyfilled promises.

There appears to be some very strange setTimeout/postMessage nesting behavior. I'm seeing

setTimeout(function(){
    setTimeout(function(){
        setTimeout(function(){
            setTimeout(function(){
                Promise.reject('err').then(function(){}).then(function(){}).catch(function(err){
                    console.log('handled error', err);
                });
            }, 0);
        }, 500);
    }, 0);
}, 500);

in Chrome print out BOTH my own console.log('handled error'); AND the internal console.error('Unhandled promise rejection'); message. It seems to be somewhat flaky, and it almost always works when the devtools are open, but if you run that code in a standalone file with just core-js, and open devtools after running it, you'll see the error.

Obviously this code is really roundabout, but this came up for me in Jasmine because of code like

waits(500);
waits(500);
runs(function(){
    // Some normal code that happens to create a promise chain like the one above.
});

I did some testing on my own machine by splitting out the core-js code and just using straight JS:

setTimeout(function(){
    setTimeout(function(){
        setTimeout(function(){
            setTimeout(function(){
                setTimeout(function(){
                    console.log('2')
                }, 1);

                window.addEventListener('message', function fn(){
                    window.removeEventListener('message', fn, false);

                    console.log('1');
                    setTimeout(function(){
                        console.log('3');
                    }, 1);
                }, false);
                window.postMessage('something', '*');
            }, 0);
        }, 500);
    }, 0);
}, 500);

prints

1
3
2

when I have devtools closed, which I think is making the promise code process the rejection in the wrong order.