-
Notifications
You must be signed in to change notification settings - Fork 1.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Lookup resolve
property only once in PerformPromiseAll and PerformPromiseRace
#1505
Comments
This change seems consistent with other parts of the language: for example, the Map constructor (and related constructors elsewhere) look up |
I’d love to see it happen; do we have any data about web compatibility? |
For this to break anyone, they would need to be replacing I would love web compat data, but this seems like one of those cases where we could decide to make the change without data and hope engines don't find they need to back it out (assuming of course that engines were on board). |
If we’re all comfortable with that, then i am too :-) i agree it seems highly unlikely. |
agreed |
var promise = new Promise(function() {});
var resolveCount = 0
var proxy = new Proxy(Promise, {
get(_, name) {
if (name === 'resolve') {
resolveCount++;
}
return Promise[name];
}
});
Promise.all.call(proxy, [promise, promise, promise]);
console.log(resolveCount); // should be 1 after this change, it's currently 3 If you prefer avoiding Proxies: var promise = new Promise(function() {});
var resolveCount = 0;
function NotPromise(executor) {
return new Promise(executor);
}
Object.defineProperty(NotPromise, 'resolve', {
get() {
resolveCount++;
return function(v) {
return Promise.resolve(v);
};
}
});
Promise.all.call(NotPromise, [promise, promise, promise]);
console.log(resolveCount); Here are some tests you can use for I support this change. You can also monkeypatch Promise.resolve directly but make sure it does not conflict with other stuff while running the tests: var promise = new Promise(function() {});
var resolveCount = 0;
var origResolve = Promise.resolve;
Object.defineProperty(Promise, 'resolve', {
get() {
resolveCount++;
return origResolve;
}
});
Promise.all([promise, promise, promise])
console.log(resolveCount); |
I’m with the “let’s just do it [in V8]” crowd. Agreed that the change seems obscure enough that I wouldn’t expect any significant breakage. I plan on merging tc39/proposal-promise-allSettled#40. @gsathya do you want to kick off a PR against ecma262 as well? |
@leobalter Can you please land your tests in test262? I'd like to have good test262 coverage before shipping this in chrome. Thanks! |
tc39/proposal-promise-allSettled#40 is now merged. Let's land the Test262 tests and get this optimization shipped in Chrome soon, so we can gather data. Thanks, everyone! |
We have tests in tc39/test262#2131. I'd like to discuss if we should change this behavior to only get the 'resolve' method if the iterable is not empty. Do we have precedent for this? |
It feels like there'd be more precedent for minimize calling user code before checking all invariants; iow, if |
I think the closest thing is the behavior of things like the Map or Set constructors, which are precedent in the other direction: they look up their adder function before consuming the iterator at all, even to check if it's empty (i.e., pretty much what #1506 does). I wouldn't think that precedent needs to be binding, if there's a reason to do things differently, but on the other hand I think the currently proposed behavior is more predictable (and it sounds like e.g. @gibson042 agrees). |
sounds reasonable. I just wanted to make sure the tests represent the proposed intent. Sounds like it already does. |
See tc39/proposal-promise-allSettled#40 for background
This would be a change similar to the one proposed with Promise.allSettled
The text was updated successfully, but these errors were encountered: