Skip to content

Rejection of a Promise that depends on another promise is extremely slow in V8/Chrome. #501

Closed
@dtinth

Description

@dtinth

The Story

First, I created a Promise, called x.

var x = new Promise(function(resolve) {
  setTimeout(resolve, 1000)
})

Then I created a function that processes a task, but it depends on x, but they all fail:

function y(task) {
  return x.then(function() { throw new Error('it failed') })
}

I have 1000 tasks, and I process them all.

Promise.all(tasks.map(y)).then(...).catch(...)

The Problem

At the moment x is resolved, on Google Chrome with a minified build, the browser freezes for ~10 seconds.

The Test Case

https://rawgit.com/dtinth/39520b129f143c66bd40/raw/index.html

The Weirdness

  • From my testing, this only happens in Google Chrome, including Chrome Canary.
    • It runs smoothly on Firefox and Safari.
  • When using native promises, this problem doesn't happen.
  • It only happens in minified builds.
    • When I use bluebird.js instead of bluebird.min.js, the problem disappears.
    • Nevertheless, when I use bluebird in webpack environment, the problem still appears.

The Profile

On my MacBook, it takes 9 seconds to settle the Promise.

screen shot 2015-02-18 at 21 02 47

Upon zooming, most time is spent on _rejectCallback.

screen shot 2015-02-18 at 21 04 13

The Variations

If y returns a promise that's eventually fulfilled (instead of rejected), this problem doesn't happen.

If each y depends on different x, this problem doesn't happen. What I mean is that x and y looks like this instead:

function x() {
  return new Promise(function(resolve) {
    setTimeout(resolve, 1000)
  })
}

function y(task) {
  return x().then(function() { throw new Error('it failed') })
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions