util: add util.promisify() #12442

Merged
merged 8 commits into from May 9, 2017

Conversation

@addaleax
Member

addaleax commented Apr 16, 2017

See nodejs/CTC#12 for discussion/background. I would say that that thread is a better place for general discussion, and I prefer it if comments here would be kept to what is directly relevant for this PR.

CI: https://ci.nodejs.org/job/node-test-commit/9143/

Checklist
  • make -j4 test (UNIX), or vcbuild test (Windows) passes
  • tests and/or benchmarks are included
  • documentation is changed or added
  • commit message follows commit guidelines
Affected core subsystem(s)

util, timers

Original commit descriptions

util: add internal bindings for promise handling

Add methods for creating, resolving and rejecting promises using the V8 C++ API that does not require creation of extra resolve and reject functions to process.binding('util').

util: add util.promisify()

Add util.promisify(function) for creating promisified functions.

Fixes: nodejs/CTC#12

timers: add promisify support

Add support for util.promisify(setTimeout) and util.promisify(setImmediate) as a proof-of-concept implementation. clearTimeout() and clearImmediate() resolve the promise immediately instead of rejecting it; that might be the most opinionated choice about this.

/cc @chrisdickinson @benjamingr @Fishrock123 @nodejs/ctc

edit: CTC voting comment

@addaleax

This comment has been minimized.

Show comment
Hide comment
@addaleax

addaleax Apr 16, 2017

Member

Also, @benjamingr has a good point about the naming, quote:

optimally I'd hope for most people to not even be aware of what a promise is in 5 years and just use async/await seamlessly :)

We can bikeshed this further here, but just to get an idea how people feel, could people 👍 this comment for “promisify sounds good” and 👎 this for “I’d prefer awaitable or something else” (both assuming that we agree on the approach in this PR in general)?

Member

addaleax commented Apr 16, 2017

Also, @benjamingr has a good point about the naming, quote:

optimally I'd hope for most people to not even be aware of what a promise is in 5 years and just use async/await seamlessly :)

We can bikeshed this further here, but just to get an idea how people feel, could people 👍 this comment for “promisify sounds good” and 👎 this for “I’d prefer awaitable or something else” (both assuming that we agree on the approach in this PR in general)?

@Fishrock123

This comment has been minimized.

Show comment
Hide comment
@Fishrock123

Fishrock123 Apr 16, 2017

Member

Maybe we should split the timers bits into a second PR? They don't map well to promises since we don't have cancelables. Maybe we could plug the timers props onto the promise itself? Not sure.

Member

Fishrock123 commented Apr 16, 2017

Maybe we should split the timers bits into a second PR? They don't map well to promises since we don't have cancelables. Maybe we could plug the timers props onto the promise itself? Not sure.

@Fishrock123

This comment has been minimized.

Show comment
Hide comment
@Fishrock123

Fishrock123 Apr 16, 2017

Member

I.e. clearTimeout() should probably work on whatever setTimeoutPromise() returns (a promise but you get the idea), same for Immediates.

Member

Fishrock123 commented Apr 16, 2017

I.e. clearTimeout() should probably work on whatever setTimeoutPromise() returns (a promise but you get the idea), same for Immediates.

@williamkapke

williamkapke suggested changes Apr 16, 2017 edited

I (also) would like to see the timers impl in a followup PR.

lib/internal/util.js
+ throw new TypeError('The first argument to promisify() must be a function');
+ }
+
+ if (orig && orig[kCustomPromisifiedSymbol]) {

This comment has been minimized.

@williamkapke

williamkapke Apr 16, 2017

Member

This truthy test of orig is not needed since it is guaranteed to be a function at this point

@williamkapke

williamkapke Apr 16, 2017

Member

This truthy test of orig is not needed since it is guaranteed to be a function at this point

This comment has been minimized.

@addaleax

addaleax Apr 16, 2017

Member

@williamkapke thanks for catching, done

@addaleax

addaleax Apr 16, 2017

Member

@williamkapke thanks for catching, done

@benjamingr benjamingr self-assigned this Apr 16, 2017

@benjamingr

This comment has been minimized.

Show comment
Hide comment
@benjamingr

benjamingr Apr 16, 2017

Member

A big +1 on this. I think this could be a great first step for helping users deal with async/await in their code. There is a clear benefit over a userland implementation, and the need is prevalent.

Member

benjamingr commented Apr 16, 2017

A big +1 on this. I think this could be a great first step for helping users deal with async/await in their code. There is a clear benefit over a userland implementation, and the need is prevalent.

@Fishrock123

This comment has been minimized.

Show comment
Hide comment
@Fishrock123

Fishrock123 Apr 16, 2017

Member

Going to expand on my point a bit: I think this is reasonable to do for simple callback APIs but I think we should spend more* time to think about how to wrap more complex APIs such as timers, child processes, etc well.

  • * Might be good for an EP?
Member

Fishrock123 commented Apr 16, 2017

Going to expand on my point a bit: I think this is reasonable to do for simple callback APIs but I think we should spend more* time to think about how to wrap more complex APIs such as timers, child processes, etc well.

  • * Might be good for an EP?
@addaleax

This comment has been minimized.

Show comment
Hide comment
@addaleax

addaleax Apr 16, 2017

Member

Maybe we should split the timers bits into a second PR?

If that’s what people here prefer, sure. I just thought it made sense because they’re about the only API that’s a bit icky because they don’t conform to Node’s standard callback pattern, so whenever we introduce something like util.promisify() we’d probably also want to have support for promisified timers (in some way).

I.e. clearTimeout() should probably work on whatever setTimeoutPromise() returns (a promise but you get the idea), same for Immediates.

Makes sense, I’ve updated the PR with isPromise(timer) checks anyway.

Member

addaleax commented Apr 16, 2017

Maybe we should split the timers bits into a second PR?

If that’s what people here prefer, sure. I just thought it made sense because they’re about the only API that’s a bit icky because they don’t conform to Node’s standard callback pattern, so whenever we introduce something like util.promisify() we’d probably also want to have support for promisified timers (in some way).

I.e. clearTimeout() should probably work on whatever setTimeoutPromise() returns (a promise but you get the idea), same for Immediates.

Makes sense, I’ve updated the PR with isPromise(timer) checks anyway.

@benjamingr

This comment has been minimized.

Show comment
Hide comment
@benjamingr

benjamingr Apr 16, 2017

Member

@Fishrock123

Going to expand on my point a bit: I think this is reasonable to do for simple callback APIs but I think we should spend more time to think about how to wrap more complex APIs such as timers, child processes, etc well.

I definitely agree - we need a proper promised core at some point - but #5020 and similar attempts have stagnated and quoting myself in the original issue:

The idea of util.awaitable vs a promise core is that it's hopefully a lot less objectionable, it poses a lot less controversy, it's a lot less opinionated and it means exposing a capability that users can build on and not an API.

Member

benjamingr commented Apr 16, 2017

@Fishrock123

Going to expand on my point a bit: I think this is reasonable to do for simple callback APIs but I think we should spend more time to think about how to wrap more complex APIs such as timers, child processes, etc well.

I definitely agree - we need a proper promised core at some point - but #5020 and similar attempts have stagnated and quoting myself in the original issue:

The idea of util.awaitable vs a promise core is that it's hopefully a lot less objectionable, it poses a lot less controversy, it's a lot less opinionated and it means exposing a capability that users can build on and not an API.

@addaleax

This comment has been minimized.

Show comment
Hide comment
@addaleax

addaleax Apr 16, 2017

Member

I think @Fishrock123’s comment was about the timers stuff, not the general API here? I feel inclined to disagree that this needs an EP, though…

Member

addaleax commented Apr 16, 2017

I think @Fishrock123’s comment was about the timers stuff, not the general API here? I feel inclined to disagree that this needs an EP, though…

@Fishrock123

This comment has been minimized.

Show comment
Hide comment
@Fishrock123

Fishrock123 Apr 16, 2017

Member

Correct. I only mean for how to wrap any APIs that are more complex than single events or callbacks and which do not wrap as well.

Member

Fishrock123 commented Apr 16, 2017

Correct. I only mean for how to wrap any APIs that are more complex than single events or callbacks and which do not wrap as well.

doc/api/util.md
+added: REPLACEME
+-->
+
+* `function` {Function}

This comment has been minimized.

@TimothyGu

TimothyGu Apr 16, 2017

Member

function isn't a legal identifier in JS, and for consistency we probably want to keep it legal.

@TimothyGu

TimothyGu Apr 16, 2017

Member

function isn't a legal identifier in JS, and for consistency we probably want to keep it legal.

+<!-- YAML
+added: REPLACEME
+-->
+

This comment has been minimized.

@TimothyGu

TimothyGu Apr 16, 2017

Member
* {symbol}
@TimothyGu

TimothyGu Apr 16, 2017

Member
* {symbol}
doc/api/util.md
+-->
+
+A Symbol that can be used to declare custom promisified variants of functions,
+see [Custom promisified functions][].

This comment has been minimized.

@TimothyGu

TimothyGu Apr 16, 2017

Member

Lower case "custom"

@TimothyGu

TimothyGu Apr 16, 2017

Member

Lower case "custom"

This comment has been minimized.

@addaleax

addaleax Apr 16, 2017

Member

I think the uppercase variant is okay here, it’s referring to a literal section title, and it matches what we do for the other two section references in this file. If you feel strongly about it I’ll change it.

@addaleax

addaleax Apr 16, 2017

Member

I think the uppercase variant is okay here, it’s referring to a literal section title, and it matches what we do for the other two section references in this file. If you feel strongly about it I’ll change it.

+setImmediatePromise('foobar').then((value) => {
+ // value === 'foobar' (passing values is optional)
+ // This is executed after all I/O callbacks.
+});

This comment has been minimized.

@TimothyGu

TimothyGu Apr 16, 2017

Member

An async function example would be cool as well.

@TimothyGu

TimothyGu Apr 16, 2017

Member

An async function example would be cool as well.

doc/api/timers.md
@@ -137,7 +169,7 @@ cancel the timer and prevent it from triggering.
added: v0.9.1
-->
-* `immediate` {Immediate} An `Immediate` object as returned by
+* `immediate` {Immediate|Promise} An `Immediate` object as returned by
[`setImmediate()`][].
Cancels an `Immediate` object created by [`setImmediate()`][].

This comment has been minimized.

@TimothyGu

TimothyGu Apr 16, 2017

Member

You probably want to clarify setImmediate() or its promisified equivalent.

@TimothyGu

TimothyGu Apr 16, 2017

Member

You probably want to clarify setImmediate() or its promisified equivalent.

doc/api/timers.md
@@ -156,7 +188,7 @@ Cancels a `Timeout` object created by [`setInterval()`][].
added: v0.0.1
-->
-* `timeout` {Timeout} A `Timeout` object as returned by [`setTimeout()`][].
+* `timeout` {Timeout|Promise} A `Timeout` object as returned by [`setTimeout()`][].
Cancels a `Timeout` object created by [`setTimeout()`][].

This comment has been minimized.

@TimothyGu

TimothyGu Apr 16, 2017

Member

Ditto.

@TimothyGu

TimothyGu Apr 16, 2017

Member

Ditto.

doc/api/util.md
+
+### Custom promisified functions
+
+Using the `util.promisify.custom` one can override the return value of

This comment has been minimized.

@TimothyGu

TimothyGu Apr 16, 2017

Member

"Using the util.promisify.custom symbol"?

@TimothyGu

TimothyGu Apr 16, 2017

Member

"Using the util.promisify.custom symbol"?

lib/internal/util.js
+ return promise;
+ };
+
+ return Object.defineProperties(fn, Object.getOwnPropertyDescriptors(orig));

This comment has been minimized.

@TimothyGu

TimothyGu Apr 16, 2017

Member

What about the prototype of orig?

@TimothyGu

TimothyGu Apr 16, 2017

Member

What about the prototype of orig?

This comment has been minimized.

@addaleax

addaleax Apr 16, 2017

Member

@TimothyGu yeah … that thought occurred to me, but I basically didn’t see how setting it would make sense here. If you prefer, I’ll add

Object.setPrototypeOf(fn, Object.getPrototypeOf(orig));
@addaleax

addaleax Apr 16, 2017

Member

@TimothyGu yeah … that thought occurred to me, but I basically didn’t see how setting it would make sense here. If you prefer, I’ll add

Object.setPrototypeOf(fn, Object.getPrototypeOf(orig));

This comment has been minimized.

@TimothyGu

TimothyGu Apr 16, 2017

Member

Yeah I don't see how it would matter that much in real world, but having that there does seem a bit more natural to me. Up to you if you want to set it or not.

@TimothyGu

TimothyGu Apr 16, 2017

Member

Yeah I don't see how it would matter that much in real world, but having that there does seem a bit more natural to me. Up to you if you want to set it or not.

This comment has been minimized.

@TimothyGu

TimothyGu Apr 16, 2017

Member

I don't think it would matter that much; it just occurred to me having the prototype being equivalent might be more natural. Up to you.

@TimothyGu

TimothyGu Apr 16, 2017

Member

I don't think it would matter that much; it just occurred to me having the prototype being equivalent might be more natural. Up to you.

This comment has been minimized.

@addaleax

addaleax Apr 16, 2017

Member

@TimothyGu I’ve included it for now, let’s see what people think.

@addaleax

addaleax Apr 16, 2017

Member

@TimothyGu I’ve included it for now, let’s see what people think.

@addaleax

This comment has been minimized.

Show comment
Hide comment
@addaleax

addaleax Apr 16, 2017

Member

@TimothyGu Addressed most of your comments, PTAL

Member

addaleax commented Apr 16, 2017

@TimothyGu Addressed most of your comments, PTAL

lib/timers.js
timer[kOnTimeout] = timer._onTimeout = null;
if (timer instanceof Timeout) {
timer.close(); // for after === 0
} else {
unenroll(timer);
}
+ } else if (isPromise(timer)) {

This comment has been minimized.

@vkurchatkin

vkurchatkin Apr 16, 2017

Member

This seems like a bad idea for many reasons. I think it's fine if you can't cancel promisified timeout until we have some generic cancellation mechanism.

@vkurchatkin

vkurchatkin Apr 16, 2017

Member

This seems like a bad idea for many reasons. I think it's fine if you can't cancel promisified timeout until we have some generic cancellation mechanism.

This comment has been minimized.

@addaleax

addaleax Apr 16, 2017

Member

This seems like a bad idea for many reasons.

Would you care to provide some? Otherwise this is just not helpful.

@addaleax

addaleax Apr 16, 2017

Member

This seems like a bad idea for many reasons.

Would you care to provide some? Otherwise this is just not helpful.

This comment has been minimized.

@vkurchatkin

vkurchatkin Apr 16, 2017

Member

First of all, attaching properties to native objects seems like a bad idea from performance perspective. Secondly, this implements ad hoc cancellation mechanism, while there is no spec on standards track or even community consensus. This approach suffers from the fact that it's not propagated and there it doesn't play nice with async-await.

I think it's fine to make promisified versions not cancellable. If you use them you are most likely not going to cancel anyway.

@vkurchatkin

vkurchatkin Apr 16, 2017

Member

First of all, attaching properties to native objects seems like a bad idea from performance perspective. Secondly, this implements ad hoc cancellation mechanism, while there is no spec on standards track or even community consensus. This approach suffers from the fact that it's not propagated and there it doesn't play nice with async-await.

I think it's fine to make promisified versions not cancellable. If you use them you are most likely not going to cancel anyway.

This comment has been minimized.

@addaleax

addaleax Apr 16, 2017

Member

First of all, attaching properties to native objects seems like a bad idea from performance perspective.

That’s true, but it’s opt-in, right?

This approach suffers from the fact that it's not propagated

What do you mean by propagated?

But yeah, I would be okay with dropping clear* support for these, at least for the time being.

@addaleax

addaleax Apr 16, 2017

Member

First of all, attaching properties to native objects seems like a bad idea from performance perspective.

That’s true, but it’s opt-in, right?

This approach suffers from the fact that it's not propagated

What do you mean by propagated?

But yeah, I would be okay with dropping clear* support for these, at least for the time being.

This comment has been minimized.

@vkurchatkin

vkurchatkin Apr 16, 2017

Member

What do you mean by propagated?

Something like this:

const promise = setTimeout(1000)
  .then(() => ...);
clearTimeout(promise); // This won't work, you need original promise
@vkurchatkin

vkurchatkin Apr 16, 2017

Member

What do you mean by propagated?

Something like this:

const promise = setTimeout(1000)
  .then(() => ...);
clearTimeout(promise); // This won't work, you need original promise

This comment has been minimized.

@jasnell

jasnell Apr 18, 2017

Member

I have to agree with @vkurchatkin on this. Until there is a standard way of canceling promises, we likely shouldn't do this.

@jasnell

jasnell Apr 18, 2017

Member

I have to agree with @vkurchatkin on this. Until there is a standard way of canceling promises, we likely shouldn't do this.

This comment has been minimized.

@addaleax

addaleax Apr 19, 2017

Member

@vkurchatkin @jasnell Okay, I’ve dropped clearTimeout/clearImmediate support. It’s a niche feature anyway and it should be easy to readjust later if we want.

@addaleax

addaleax Apr 19, 2017

Member

@vkurchatkin @jasnell Okay, I’ve dropped clearTimeout/clearImmediate support. It’s a niche feature anyway and it should be easy to readjust later if we want.

lib/internal/util.js
+const kCustomPromisifiedSymbol = Symbol('util.promisify.custom');
+function promisify(orig) {
+ if (typeof orig !== 'function') {
+ throw new TypeError('The first argument to promisify() must be a function');

This comment has been minimized.

@thefourtheye

thefourtheye Apr 16, 2017

Contributor

Nit: first may not be necessary here

@thefourtheye

thefourtheye Apr 16, 2017

Contributor

Nit: first may not be necessary here

This comment has been minimized.

@addaleax

addaleax Apr 16, 2017

Member

You’re right. I wanted to phrase this error message in a way that makes it as unlikely as possible that changing it is semver-major, but if you prefer another wording, I’ll gladly change it. 😄

@addaleax

addaleax Apr 16, 2017

Member

You’re right. I wanted to phrase this error message in a way that makes it as unlikely as possible that changing it is semver-major, but if you prefer another wording, I’ll gladly change it. 😄

This comment has been minimized.

@thefourtheye

thefourtheye Apr 16, 2017

Contributor

I was thinking maybe we can just drop first. When I read the error message, my mind understood that as there are more than one argument. Not a big deal though.

@thefourtheye

thefourtheye Apr 16, 2017

Contributor

I was thinking maybe we can just drop first. When I read the error message, my mind understood that as there are more than one argument. Not a big deal though.

lib/internal/util.js
+ if (err) {
+ promiseReject(promise, err);
+ } else {
+ promiseResolve(promise, data);

This comment has been minimized.

@thefourtheye

thefourtheye Apr 16, 2017

Contributor

There are few cases where we pass more than one value like in fs.read

@thefourtheye

thefourtheye Apr 16, 2017

Contributor

There are few cases where we pass more than one value like in fs.read

This comment has been minimized.

@addaleax

addaleax Apr 16, 2017

Member

So … if you like, I can check for those APIs and add custom code for them in this PR? I think that makes sense but maybe not everybody is comfortable with yet more changes in here…

@addaleax

addaleax Apr 16, 2017

Member

So … if you like, I can check for those APIs and add custom code for them in this PR? I think that makes sense but maybe not everybody is comfortable with yet more changes in here…

This comment has been minimized.

@thefourtheye

thefourtheye Apr 16, 2017

Contributor

We can use rest operator with data and with an if condition this can be fixed, right? Only thing is the resolved value will be an array for these special cases.

@thefourtheye

thefourtheye Apr 16, 2017

Contributor

We can use rest operator with data and with an if condition this can be fixed, right? Only thing is the resolved value will be an array for these special cases.

This comment has been minimized.

@addaleax

addaleax Apr 16, 2017

Member

@thefourtheye We have about 6 top-level functions doing that, I’ve taken a stab at addressing them in a clean way in this PR (see the most recent 3 commits)… please take a look :)

@addaleax

addaleax Apr 16, 2017

Member

@thefourtheye We have about 6 top-level functions doing that, I’ve taken a stab at addressing them in a clean way in this PR (see the most recent 3 commits)… please take a look :)

lib/timers.js
+ if (isPromise(immediate))
+ immediate = immediate.timer;
+
+ if (typeof immediate._onImmediate !== 'function') {

This comment has been minimized.

@TimothyGu

TimothyGu Apr 16, 2017

Member

If the original immediate was a promise not coming from setImmediate(), immediate should be undefined here, and this might crash. Not sure if we want that.

@TimothyGu

TimothyGu Apr 16, 2017

Member

If the original immediate was a promise not coming from setImmediate(), immediate should be undefined here, and this might crash. Not sure if we want that.

This comment has been minimized.

@addaleax

addaleax Apr 16, 2017

Member

This code doesn’t have any typechecks right now anyway, you can just pass in anything and hope it doesn’t go up in flames.

@addaleax

addaleax Apr 16, 2017

Member

This code doesn’t have any typechecks right now anyway, you can just pass in anything and hope it doesn’t go up in flames.

lib/internal/util.js
+ return promise;
+ };
+
+ return Object.defineProperties(fn, Object.getOwnPropertyDescriptors(orig));

This comment has been minimized.

@TimothyGu

TimothyGu Apr 16, 2017

Member

I don't think it would matter that much; it just occurred to me having the prototype being equivalent might be more natural. Up to you.

@TimothyGu

TimothyGu Apr 16, 2017

Member

I don't think it would matter that much; it just occurred to me having the prototype being equivalent might be more natural. Up to you.

+ auto maybe_resolver = Promise::Resolver::New(context);
+ if (!maybe_resolver.IsEmpty())
+ args.GetReturnValue().Set(maybe_resolver.ToLocalChecked());
+}

This comment has been minimized.

@TimothyGu

TimothyGu Apr 16, 2017

Member

Is this function basically equivalent to passing a dummy function to the Promise constructor?

@TimothyGu

TimothyGu Apr 16, 2017

Member

Is this function basically equivalent to passing a dummy function to the Promise constructor?

This comment has been minimized.

@addaleax

addaleax Apr 16, 2017

Member

I think so. It’s using V8s internal promise creation mechanism instead of the full Promise constructor … I would assume the latter is built upon the former, but I haven’t checked that. If you want, I can try to look it up.

@addaleax

addaleax Apr 16, 2017

Member

I think so. It’s using V8s internal promise creation mechanism instead of the full Promise constructor … I would assume the latter is built upon the former, but I haven’t checked that. If you want, I can try to look it up.

This comment has been minimized.

@littledan

littledan Apr 21, 2017

This is internally implemented by basically calling new Promise() with no closure argument. However, the great thing is that, since you're using the V8 API, you can still resolve and reject it, even though no closures are allocated (because they won't leak).

@littledan

littledan Apr 21, 2017

This is internally implemented by basically calling new Promise() with no closure argument. However, the great thing is that, since you're using the V8 API, you can still resolve and reject it, even though no closures are allocated (because they won't leak).

lib/internal/util.js
+ return promise;
+ };
+
+ Object.setPrototypeOf(fn, Object.getPrototypeOf(orig));

This comment has been minimized.

@TimothyGu

TimothyGu Apr 16, 2017

Member

I'd make sure this doesn't decrease the performance of getting fn's properties; if in doubt, an if (Object.getPrototypeOf(fn) !== Object.getPrototypeOf(orig)) might be good.

@TimothyGu

TimothyGu Apr 16, 2017

Member

I'd make sure this doesn't decrease the performance of getting fn's properties; if in doubt, an if (Object.getPrototypeOf(fn) !== Object.getPrototypeOf(orig)) might be good.

This comment has been minimized.

@addaleax

addaleax Apr 16, 2017

Member

V8 implements setPrototypeOf as a no-op if they are already equal, I’ve checked that in the past to be sure. 😄

@addaleax

addaleax Apr 16, 2017

Member

V8 implements setPrototypeOf as a no-op if they are already equal, I’ve checked that in the past to be sure. 😄

src/node_util.cc
+ Local<Context> context = args.GetIsolate()->GetCurrentContext();
+ Local<Value> promise = args[0];
+ CHECK(promise->IsPromise());
+ ASSERT_EQ(promise.As<Promise>()->State(), Promise::kPending);

This comment has been minimized.

@thefourtheye

thefourtheye Apr 16, 2017

Contributor

Promises are idempotent right? Should we really do this?

@thefourtheye

thefourtheye Apr 16, 2017

Contributor

Promises are idempotent right? Should we really do this?

This comment has been minimized.

@benjamingr

benjamingr Apr 16, 2017

Member

It's to check that the promise is pending at that point. It might not be necessary but not because of idempotence.

@benjamingr

benjamingr Apr 16, 2017

Member

It's to check that the promise is pending at that point. It might not be necessary but not because of idempotence.

This comment has been minimized.

@addaleax

addaleax Apr 16, 2017

Member

Hm, maybe it is necessary to always check for that… some really weird userland functions could schedule the callback to run and then throw after that. (And using this code would actually change the Promise state.)

@addaleax

addaleax Apr 16, 2017

Member

Hm, maybe it is necessary to always check for that… some really weird userland functions could schedule the callback to run and then throw after that. (And using this code would actually change the Promise state.)

This comment has been minimized.

@addaleax

addaleax Apr 16, 2017

Member

I’ve updated this to return as a no-op when the promise is not pending.

@addaleax

addaleax Apr 16, 2017

Member

I’ve updated this to return as a no-op when the promise is not pending.

+ Local<Context> context = args.GetIsolate()->GetCurrentContext();
+ Local<Value> promise = args[0];
+ CHECK(promise->IsPromise());
+ if (promise.As<Promise>()->State() != Promise::kPending) return;

This comment has been minimized.

@thefourtheye

thefourtheye Apr 16, 2017

Contributor

Nice, this looks better than the throwing to me. Thanks :)

@thefourtheye

thefourtheye Apr 16, 2017

Contributor

Nice, this looks better than the throwing to me. Thanks :)

lib/internal/util.js
+ if (values.length === 1)
+ promiseResolve(promise, values[0]);
+ else
+ promiseResolve(promise, values);

This comment has been minimized.

@thefourtheye

thefourtheye Apr 16, 2017

Contributor

We may need another condition here for callbacks which don't return anything interesting, like rmdir

@thefourtheye

thefourtheye Apr 16, 2017

Contributor

We may need another condition here for callbacks which don't return anything interesting, like rmdir

This comment has been minimized.

@addaleax

addaleax Apr 16, 2017

Member

@thefourtheye thanks for catching, done

@addaleax

addaleax Apr 16, 2017

Member

@thefourtheye thanks for catching, done

This comment has been minimized.

@thefourtheye

thefourtheye Apr 17, 2017

Contributor

There is only one case where this will fail, fs.exists. But we don't have to worry much about it anyway I guess, as it is deprecated.

@thefourtheye

thefourtheye Apr 17, 2017

Contributor

There is only one case where this will fail, fs.exists. But we don't have to worry much about it anyway I guess, as it is deprecated.

@addaleax

This comment has been minimized.

Show comment
Hide comment
@addaleax

addaleax Apr 16, 2017

Member

@benjamingr @TimothyGu It’s nice to see support so soon, but you may want to give the changes here based on @thefourtheye’s comments a look, I don’t want to just assume they LGTY too

edit: new CI: https://ci.nodejs.org/job/node-test-commit/9146/
https://ci.nodejs.org/job/node-test-commit/9147/
https://ci.nodejs.org/job/node-test-commit/9148/ (green 🎉)

Member

addaleax commented Apr 16, 2017

@benjamingr @TimothyGu It’s nice to see support so soon, but you may want to give the changes here based on @thefourtheye’s comments a look, I don’t want to just assume they LGTY too

edit: new CI: https://ci.nodejs.org/job/node-test-commit/9146/
https://ci.nodejs.org/job/node-test-commit/9147/
https://ci.nodejs.org/job/node-test-commit/9148/ (green 🎉)

@vkurchatkin

This comment has been minimized.

Show comment
Hide comment
@vkurchatkin

vkurchatkin Apr 16, 2017

Member

One more thing to consider: util.promisify won't play nice with typecheckers, such as Flow and Typescript. For this reason I personally would prefer to have promisifed versions of built-in modules out of the box.

Member

vkurchatkin commented Apr 16, 2017

One more thing to consider: util.promisify won't play nice with typecheckers, such as Flow and Typescript. For this reason I personally would prefer to have promisifed versions of built-in modules out of the box.

@benjamingr

This comment has been minimized.

Show comment
Hide comment
@benjamingr

benjamingr Apr 16, 2017

Member

@vkurchatkin mind elaborating? Since TypeScript 2.2 and keyof I've been able to get perfectly decent typings with TypeScript - you can specify the type as "takes a function that takes N arguments and a node callback and return a function that takes N arguments and returns a promise".

Member

benjamingr commented Apr 16, 2017

@vkurchatkin mind elaborating? Since TypeScript 2.2 and keyof I've been able to get perfectly decent typings with TypeScript - you can specify the type as "takes a function that takes N arguments and a node callback and return a function that takes N arguments and returns a promise".

@vkurchatkin

This comment has been minimized.

Show comment
Hide comment
@vkurchatkin

vkurchatkin Apr 16, 2017

Member

@benjamingr I guess you could declare overloads for some sufficient number of arguments (in both Flow and TS), but it's not so nice and also won't work with custom promisified implementations.

Member

vkurchatkin commented Apr 16, 2017

@benjamingr I guess you could declare overloads for some sufficient number of arguments (in both Flow and TS), but it's not so nice and also won't work with custom promisified implementations.

@benjamingr

This comment has been minimized.

Show comment
Hide comment
@benjamingr

benjamingr Apr 17, 2017

Member

@addaleax I'm still LGTM but would rather have this split into two PRs - one just addzing promisify (as awaitable) without touching any core methods and one adding the rest of the API

Member

benjamingr commented Apr 17, 2017

@addaleax I'm still LGTM but would rather have this split into two PRs - one just addzing promisify (as awaitable) without touching any core methods and one adding the rest of the API

@@ -184,3 +185,13 @@ TEST(function test_lookupservice_ip_ipv4(done) {
checkWrap(req);
});
+
+TEST(function test_lookupservice_ip_ipv4_promise(done) {
+ util.promisify(dns.lookupService)('127.0.0.1', 80)

This comment has been minimized.

@evanlucas

evanlucas Apr 17, 2017

Member

do we want an unhandled rejection handler here? Or at least a .catch()?

@evanlucas

evanlucas Apr 17, 2017

Member

do we want an unhandled rejection handler here? Or at least a .catch()?

This comment has been minimized.

@addaleax

addaleax Apr 17, 2017

Member

@evanlucas Ah, right… added the unhandled rejection handler, like in the other tests

@addaleax

addaleax Apr 17, 2017

Member

@evanlucas Ah, right… added the unhandled rejection handler, like in the other tests

@addaleax

This comment has been minimized.

Show comment
Hide comment
@addaleax

addaleax Apr 17, 2017

Member

@benjamingr So … I’ve thought about this a bit, and I’m not sure the advantages in splitting this up are large enough to me; we can obviously land the changes for the built-in modules separately, but they should definitely be released together. And if there is non-trivial feedback on the timers/child_process/fs/dns changes, I’d say there’s a good chance we would take a look at util.promisify itself to see if changes in it would help address that feedback.

Member

addaleax commented Apr 17, 2017

@benjamingr So … I’ve thought about this a bit, and I’m not sure the advantages in splitting this up are large enough to me; we can obviously land the changes for the built-in modules separately, but they should definitely be released together. And if there is non-trivial feedback on the timers/child_process/fs/dns changes, I’d say there’s a good chance we would take a look at util.promisify itself to see if changes in it would help address that feedback.

@thefourtheye

This comment has been minimized.

Show comment
Hide comment
@thefourtheye

thefourtheye Apr 17, 2017

Contributor

@addaleax As far as I know the current implementation will fail only for fs.exists. Since its usage is discouraged, we don't have to spend much time on it I think.

Contributor

thefourtheye commented Apr 17, 2017

@addaleax As far as I know the current implementation will fail only for fs.exists. Since its usage is discouraged, we don't have to spend much time on it I think.

dns: support promisified `lookup(Service)`
PR-URL: #12442
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
Reviewed-By: William Kapke <william.kapke@gmail.com>
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Teddy Katz <teddy.katz@gmail.com>
@addaleax

This comment has been minimized.

Show comment
Hide comment
@addaleax

addaleax May 9, 2017

Member

Landed in f72376d...faf6654

Thanks everyone for the reviews and support!

Member

addaleax commented May 9, 2017

Landed in f72376d...faf6654

Thanks everyone for the reviews and support!

@addaleax addaleax closed this May 9, 2017

@addaleax addaleax merged commit faf6654 into nodejs:master May 9, 2017

@addaleax addaleax deleted the addaleax:promisify branch May 9, 2017

@benjamingr

This comment has been minimized.

Show comment
Hide comment
@benjamingr

benjamingr May 9, 2017

Member

@addaleax going to give a small talk about this journey on Thursday, starting in nodejs/node-v0.x-archive#7642

Thanks a ton for taking up the glove and working together on the conceptual side, while undertaking the vast majority of the technical burden. Props for the execution and delivery, and thank you :)

Member

benjamingr commented May 9, 2017

@addaleax going to give a small talk about this journey on Thursday, starting in nodejs/node-v0.x-archive#7642

Thanks a ton for taking up the glove and working together on the conceptual side, while undertaking the vast majority of the technical burden. Props for the execution and delivery, and thank you :)

@thefourtheye

This comment has been minimized.

Show comment
Hide comment
@thefourtheye

thefourtheye May 9, 2017

Contributor

@MadaraUchiha You were right! This PR is @benjamingr's birthday present 😉

Contributor

thefourtheye commented May 9, 2017

@MadaraUchiha You were right! This PR is @benjamingr's birthday present 😉

@addaleax addaleax removed the ctc-agenda label May 9, 2017

@aendrew

This comment has been minimized.

Show comment
Hide comment
@aendrew

aendrew May 12, 2017

🙌 * 9001 — so excited for this.

Will it be in 8.x, then?

🙌 * 9001 — so excited for this.

Will it be in 8.x, then?

This comment has been minimized.

Show comment
Hide comment
@addaleax

addaleax May 12, 2017

Member

@aendrew Yes! :) Have an RC: https://nodejs.org/download/rc/v8.0.0-rc.0/ The 8.0.0 release itself is planned for/by May 30th. :)

Member

addaleax replied May 12, 2017

@aendrew Yes! :) Have an RC: https://nodejs.org/download/rc/v8.0.0-rc.0/ The 8.0.0 release itself is planned for/by May 30th. :)

This comment has been minimized.

Show comment
Hide comment
@styfle

styfle May 12, 2017

Contributor

@aendrew Yes it will, very exciting! I wrote some of my first thoughts on Medium.

Contributor

styfle replied May 12, 2017

@aendrew Yes it will, very exciting! I wrote some of my first thoughts on Medium.

This comment has been minimized.

Show comment
Hide comment
@markstos

markstos May 12, 2017

Contributor

Why is this in the util. name space and not in the Promise namespace, which seems far more natural?

Contributor

markstos replied May 12, 2017

Why is this in the util. name space and not in the Promise namespace, which seems far more natural?

This comment has been minimized.

Show comment
Hide comment
@addaleax

addaleax May 12, 2017

Member

Why is this in the util. name space

Because it’s an utility function. If you have a better place in Node core where it should be (Promise doesn’t count for that, see below), we can revisit that. I haven’t seen any, though. :)

and not in the Promise namespace, which seems far more natural?

Because Promise is a language built-in, not something that Node offers. We try to avoid messing with built-in object as much as possible, so that users know they may rely on those having the same features available in other environments as Node.

Member

addaleax replied May 12, 2017

Why is this in the util. name space

Because it’s an utility function. If you have a better place in Node core where it should be (Promise doesn’t count for that, see below), we can revisit that. I haven’t seen any, though. :)

and not in the Promise namespace, which seems far more natural?

Because Promise is a language built-in, not something that Node offers. We try to avoid messing with built-in object as much as possible, so that users know they may rely on those having the same features available in other environments as Node.

This comment has been minimized.

Show comment
Hide comment
@markstos

markstos May 12, 2017

Contributor

@addaleax Thanks for the prompt and clear response.

I appreciate the attempt to be compatible with other JavaScript environments. I'm part of the group of largely backend-only developers, so I don't notice the compatibility differences with JavaScript engines in browsers, but I do use a mix of native and bluebird promises on the backend. When it comes to comparing to bluebird and other promise libraries, the choice of the util namespace is confusingly different when there's already a precedent for Promise.promisify existing and working exactly the same as util.promisify().

What would be more useful to be would be:

    // All the methods from the native `Promise` namespace, 
    // plus `promisify()` in one convenient location
    var Promise = require('node.Promise')

This solution be non-conflicting-- an understandable goal-- but still clear and convenient. Loading most Promise methods from Promise but then loading just one from util. would be both confusing and inconsistent.

In my example, I use the new node. namespace for a sub-namespace that might conflict with a native namespace, but that has been modified or extended for Node.js.

Contributor

markstos replied May 12, 2017

@addaleax Thanks for the prompt and clear response.

I appreciate the attempt to be compatible with other JavaScript environments. I'm part of the group of largely backend-only developers, so I don't notice the compatibility differences with JavaScript engines in browsers, but I do use a mix of native and bluebird promises on the backend. When it comes to comparing to bluebird and other promise libraries, the choice of the util namespace is confusingly different when there's already a precedent for Promise.promisify existing and working exactly the same as util.promisify().

What would be more useful to be would be:

    // All the methods from the native `Promise` namespace, 
    // plus `promisify()` in one convenient location
    var Promise = require('node.Promise')

This solution be non-conflicting-- an understandable goal-- but still clear and convenient. Loading most Promise methods from Promise but then loading just one from util. would be both confusing and inconsistent.

In my example, I use the new node. namespace for a sub-namespace that might conflict with a native namespace, but that has been modified or extended for Node.js.

addaleax added a commit to addaleax/node that referenced this pull request May 18, 2017

test: introduce `common.crashOnUnhandledRejection`
Ref: nodejs#12442
PR-URL: nodejs#12489
Reviewed-By: Matthew Loring <mattloring@google.com>
Reviewed-By: Julien Gilli <jgilli@nodejs.org>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

addaleax added a commit to addaleax/node that referenced this pull request May 18, 2017

test: introduce `common.crashOnUnhandledRejection`
Ref: nodejs#12442
PR-URL: nodejs#12489
Reviewed-By: Matthew Loring <mattloring@google.com>
Reviewed-By: Julien Gilli <jgilli@nodejs.org>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

anchnk added a commit to anchnk/node that referenced this pull request May 19, 2017

util: add internal bindings for promise handling
Add methods for creating, resolving and rejecting promises
using the V8 C++ API that does not require creation of extra
`resolve` and `reject` functions to `process.binding('util')`.

PR-URL: nodejs#12442
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
Reviewed-By: William Kapke <william.kapke@gmail.com>
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Teddy Katz <teddy.katz@gmail.com>

anchnk added a commit to anchnk/node that referenced this pull request May 19, 2017

util: add util.promisify()
Add `util.promisify(function)` for creating promisified functions.
Includes documentation and tests.

Fixes: nodejs/CTC#12
PR-URL: nodejs#12442
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
Reviewed-By: William Kapke <william.kapke@gmail.com>
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Teddy Katz <teddy.katz@gmail.com>

anchnk added a commit to anchnk/node that referenced this pull request May 19, 2017

test: add a bunch of tests from bluebird
Take tests from Bluebird's promisify's tests and adapted them to the
format in use here.
Add tests making sure things work with async functions.
Add basic usability tests.

PR-URL: nodejs#12442
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
Reviewed-By: William Kapke <william.kapke@gmail.com>
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Teddy Katz <teddy.katz@gmail.com>

anchnk added a commit to anchnk/node that referenced this pull request May 19, 2017

test: add test for promisify customPromisifyArgs
PR-URL: nodejs#12442
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
Reviewed-By: William Kapke <william.kapke@gmail.com>
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Teddy Katz <teddy.katz@gmail.com>

anchnk added a commit to anchnk/node that referenced this pull request May 19, 2017

timers: add promisify support
Add support for `util.promisify(setTimeout)` and
`util.promisify(setImmediate)` as a proof-of-concept implementation.
`clearTimeout()` and `clearImmediate()` do not work on those Promises.
Includes documentation and tests.

PR-URL: nodejs#12442
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
Reviewed-By: William Kapke <william.kapke@gmail.com>
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Teddy Katz <teddy.katz@gmail.com>

anchnk added a commit to anchnk/node that referenced this pull request May 19, 2017

fs: support util.promisify for fs.read/fs.write
PR-URL: nodejs#12442
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
Reviewed-By: William Kapke <william.kapke@gmail.com>
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Teddy Katz <teddy.katz@gmail.com>

anchnk added a commit to anchnk/node that referenced this pull request May 19, 2017

child_process: support promisified `exec(File)`
Author: Benjamin Gruenbaum <inglor@gmail.com>
Author: Anna Henningsen <anna@addaleax.net>

PR-URL: nodejs#12442
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
Reviewed-By: William Kapke <william.kapke@gmail.com>
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Teddy Katz <teddy.katz@gmail.com>

anchnk added a commit to anchnk/node that referenced this pull request May 19, 2017

dns: support promisified `lookup(Service)`
PR-URL: nodejs#12442
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Myles Borins <myles.borins@gmail.com>
Reviewed-By: Evan Lucas <evanlucas@me.com>
Reviewed-By: William Kapke <william.kapke@gmail.com>
Reviewed-By: Timothy Gu <timothygu99@gmail.com>
Reviewed-By: Teddy Katz <teddy.katz@gmail.com>

@jasnell jasnell referenced this pull request May 11, 2017

Closed

8.0.0 Release Proposal #12220

jasnell added a commit to jasnell/node that referenced this pull request May 29, 2017

2017-05-30, Version 8.0.0 (Current)
* **Async Hooks**
  * The `async_hooks` module has landed in core
    [[`4a7233c178`](nodejs@4a7233c]
    [#12892](nodejs#12892).

* **Buffer**
  * Using the `--pending-deprecation` flag will cause Node.js to emit a
    deprecation warning when using `new Buffer(num)` or `Buffer(num)`.
    [[`d2d32ea5a2`](nodejs@d2d32ea]
    [#11968](nodejs#11968).
  * `new Buffer(num)` and `Buffer(num)` will zero-fill new `Buffer` instances
    [[`7eb1b4658e`](nodejs@7eb1b46]
    [#12141](nodejs#12141).
  * Many `Buffer` methods now accept `Uint8Array` as input
    [[`beca3244e2`](nodejs@beca324]
    [#10236](nodejs#10236).

* **Child Process**
  * Argument and kill signal validations have been improved
    [[`97a77288ce`](nodejs@97a7728]
    [#12348](nodejs#12348),
    [[`d75fdd96aa`](nodejs@d75fdd9]
    [#10423](nodejs#10423).
  * Child Process methods accept `Uint8Array` as input
    [[`627ecee9ed`](nodejs@627ecee]
    [#10653](nodejs#10653).

* **Console**
  * Error events emitted when using `console` methods are now supressed.
    [[`f18e08d820`](nodejs@f18e08d]
    [#9744](nodejs#9744).

* **Dependencies**
  * The npm client has been updated to 5.0.0
    [[`3c3b36af0f`](nodejs@3c3b36a]
    [#12936](nodejs#12936).
  * V8 has been updated to 5.8 with forward ABI stability to 6.0
    [[`60d1aac8d2`](nodejs@60d1aac]
    [#12784](nodejs#12784).

* **Domains**
  * Native `Promise` instances are now `Domain` aware
    [[`84dabe8373`](nodejs@84dabe8]
    [#12489](nodejs#12489).

* **Errors**
  * We have started assigning static error codes to errors generated by Node.js.
    This has been done through multiple commits and is still a work in
    progress.

* **File System**
  * The utility class `fs.SyncWriteStream` has been deprecated
    [[`7a55e34ef4`](nodejs@7a55e34]
    [#10467](nodejs#10467).
  * The deprecated `fs.read()` string interface has been removed
    [[`3c2a9361ff`](nodejs@3c2a936]
    [#9683](nodejs#9683).

* **HTTP**
  * Improved support for userland implemented Agents
    [[`90403dd1d0`](nodejs@90403dd]
    [#11567](nodejs#11567).
  * Outgoing Cookie headers are concatenated into a single string
    [[`d3480776c7`](nodejs@d348077]
    [#11259](nodejs#11259).
  * The `httpResponse.writeHeader()` method has been deprecated
    [[`fb71ba4921`](nodejs@fb71ba4]
    [#11355](nodejs#11355).
  * New methods for accessing HTTP headers have been added to `OutgoingMessage`
    [[`3e6f1032a4`](nodejs@3e6f103]
    [#10805](nodejs#10805).

* **Lib**
  * All deprecation messages have been assigned static identifiers
    [[`5de3cf099c`](nodejs@5de3cf0]
    [#10116](nodejs#10116).
  * The legacy `linkedlist` module has been removed
    [[`84a23391f6`](nodejs@84a2339]
    [#12113](nodejs#12113).

* **N-API**
  * Experimental support for the new N-API API has been added
    [[`56e881d0b0`](nodejs@56e881d]
    [#11975](nodejs#11975).

* **Process**
  * Process warning output can be redirected to a file using the
    `--redirect-warnings` command-line argument
    [[`03e89b3ff2`](nodejs@03e89b3]
    [#10116](nodejs#10116).
  * Process warnings may now include additional detail
    [[`dd20e68b0f`](nodejs@dd20e68]
    [#12725](nodejs#12725).

* **REPL**
  * REPL magic mode has been deprecated
    [[`3f27f02da0`](nodejs@3f27f02]
    [#11599](nodejs#11599).

* **Src**
  * `NODE_MODULE_VERSION` has been updated to 57
    (nodejs@ec7cbaf]
    [#12995](nodejs#12995).
  * Add `--pending-deprecation` command-line argument and
    `NODE_PENDING_DEPRECATION` environment variable
    [[`a16b570f8c`](nodejs@a16b570]
    [#11968](nodejs#11968).
  * The `--debug` command-line argument has been deprecated. Note that
    using `--debug` will enable the *new* Inspector-based debug protocol
    as the legacy Debugger protocol previously used by Node.js has been
    removed. [[`010f864426`](nodejs@010f864]
    [#12949](nodejs#12949).
  * Throw when the `-c` and `-e` command-line arguments are used at the same
    time [[`a5f91ab230`](nodejs@a5f91ab]
    [#11689](nodejs#11689).
  * Throw when the `--use-bundled-ca` and `--use-openssl-ca` command-line
    arguments are used at the same time.
    [[`8a7db9d4b5`](nodejs@8a7db9d]
    [#12087](nodejs#12087).

* **Stream**
  * `Stream` now supports `destroy()` and `_destroy()` APIs
    [[`b6e1d22fa6`](nodejs@b6e1d22]
    [#12925](nodejs#12925).
  * `Stream` now supports the `_final()` API
    [[`07c7f198db`](nodejs@07c7f19]
    [#12828](nodejs#12828).

* **TLS**
  * The `rejectUnauthorized` option now defaults to `true`
    [[`348cc80a3c`](nodejs@348cc80]
    [#5923](nodejs#5923).
  * The `tls.createSecurePair()` API now emits a runtime deprecation
    [[`a2ae08999b`](nodejs@a2ae089]
    [#11349](nodejs#11349).
  * A runtime deprecation will now be emitted when `dhparam` is less than
    2048 bits [[`d523eb9c40`](nodejs@d523eb9]
    [#11447](nodejs#11447).

* **URL**
  * The WHATWG URL implementation is now a fully-supported Node.js API
    [[`d080ead0f9`](nodejs@d080ead]
    [#12710](nodejs#12710).

* **Util**
  * `Symbol` keys are now displayed by default when using `util.inspect()`
    [[`5bfd13b81e`](nodejs@5bfd13b]
    [#9726](nodejs#9726).
  * `toJSON` errors will be thrown when formatting `%j`
    [[`455e6f1dd8`](nodejs@455e6f1]
    [#11708](nodejs#11708).
  * Convert `inspect.styles` and `inspect.colors` to prototype-less objects
    [[`aab0d202f8`](nodejs@aab0d20]
    [#11624](nodejs#11624).
  * The new `util.promisify()` API has been added
    [[`99da8e8e02`](nodejs@99da8e8]
    [#12442](nodejs#12442).

* **Zlib**
  * Support `Uint8Array` in Zlib convenience methods
    [[`91383e47fd`](nodejs@91383e4]
    [#12001](nodejs#12001).
  * Zlib errors now use `RangeError` and `TypeError` consistently
    [[`b514bd231e`](nodejs@b514bd2]
    [#11391](nodejs#11391).

jasnell added a commit that referenced this pull request May 30, 2017

2017-05-30, Version 8.0.0 (Current)
* **Async Hooks**
  * The `async_hooks` module has landed in core
    [[`4a7233c178`](4a7233c]
    [#12892](#12892).

* **Buffer**
  * Using the `--pending-deprecation` flag will cause Node.js to emit a
    deprecation warning when using `new Buffer(num)` or `Buffer(num)`.
    [[`d2d32ea5a2`](d2d32ea]
    [#11968](#11968).
  * `new Buffer(num)` and `Buffer(num)` will zero-fill new `Buffer` instances
    [[`7eb1b4658e`](7eb1b46]
    [#12141](#12141).
  * Many `Buffer` methods now accept `Uint8Array` as input
    [[`beca3244e2`](beca324]
    [#10236](#10236).

* **Child Process**
  * Argument and kill signal validations have been improved
    [[`97a77288ce`](97a7728]
    [#12348](#12348),
    [[`d75fdd96aa`](d75fdd9]
    [#10423](#10423).
  * Child Process methods accept `Uint8Array` as input
    [[`627ecee9ed`](627ecee]
    [#10653](#10653).

* **Console**
  * Error events emitted when using `console` methods are now supressed.
    [[`f18e08d820`](f18e08d]
    [#9744](#9744).

* **Dependencies**
  * The npm client has been updated to 5.0.0
    [[`3c3b36af0f`](3c3b36a]
    [#12936](#12936).
  * V8 has been updated to 5.8 with forward ABI stability to 6.0
    [[`60d1aac8d2`](60d1aac]
    [#12784](#12784).

* **Domains**
  * Native `Promise` instances are now `Domain` aware
    [[`84dabe8373`](84dabe8]
    [#12489](#12489).

* **Errors**
  * We have started assigning static error codes to errors generated by Node.js.
    This has been done through multiple commits and is still a work in
    progress.

* **File System**
  * The utility class `fs.SyncWriteStream` has been deprecated
    [[`7a55e34ef4`](7a55e34]
    [#10467](#10467).
  * The deprecated `fs.read()` string interface has been removed
    [[`3c2a9361ff`](3c2a936]
    [#9683](#9683).

* **HTTP**
  * Improved support for userland implemented Agents
    [[`90403dd1d0`](90403dd]
    [#11567](#11567).
  * Outgoing Cookie headers are concatenated into a single string
    [[`d3480776c7`](d348077]
    [#11259](#11259).
  * The `httpResponse.writeHeader()` method has been deprecated
    [[`fb71ba4921`](fb71ba4]
    [#11355](#11355).
  * New methods for accessing HTTP headers have been added to `OutgoingMessage`
    [[`3e6f1032a4`](3e6f103]
    [#10805](#10805).

* **Lib**
  * All deprecation messages have been assigned static identifiers
    [[`5de3cf099c`](5de3cf0]
    [#10116](#10116).
  * The legacy `linkedlist` module has been removed
    [[`84a23391f6`](84a2339]
    [#12113](#12113).

* **N-API**
  * Experimental support for the new N-API API has been added
    [[`56e881d0b0`](56e881d]
    [#11975](#11975).

* **Process**
  * Process warning output can be redirected to a file using the
    `--redirect-warnings` command-line argument
    [[`03e89b3ff2`](03e89b3]
    [#10116](#10116).
  * Process warnings may now include additional detail
    [[`dd20e68b0f`](dd20e68]
    [#12725](#12725).

* **REPL**
  * REPL magic mode has been deprecated
    [[`3f27f02da0`](3f27f02]
    [#11599](#11599).

* **Src**
  * `NODE_MODULE_VERSION` has been updated to 57
    (ec7cbaf]
    [#12995](#12995).
  * Add `--pending-deprecation` command-line argument and
    `NODE_PENDING_DEPRECATION` environment variable
    [[`a16b570f8c`](a16b570]
    [#11968](#11968).
  * The `--debug` command-line argument has been deprecated. Note that
    using `--debug` will enable the *new* Inspector-based debug protocol
    as the legacy Debugger protocol previously used by Node.js has been
    removed. [[`010f864426`](010f864]
    [#12949](#12949).
  * Throw when the `-c` and `-e` command-line arguments are used at the same
    time [[`a5f91ab230`](a5f91ab]
    [#11689](#11689).
  * Throw when the `--use-bundled-ca` and `--use-openssl-ca` command-line
    arguments are used at the same time.
    [[`8a7db9d4b5`](8a7db9d]
    [#12087](#12087).

* **Stream**
  * `Stream` now supports `destroy()` and `_destroy()` APIs
    [[`b6e1d22fa6`](b6e1d22]
    [#12925](#12925).
  * `Stream` now supports the `_final()` API
    [[`07c7f198db`](07c7f19]
    [#12828](#12828).

* **TLS**
  * The `rejectUnauthorized` option now defaults to `true`
    [[`348cc80a3c`](348cc80]
    [#5923](#5923).
  * The `tls.createSecurePair()` API now emits a runtime deprecation
    [[`a2ae08999b`](a2ae089]
    [#11349](#11349).
  * A runtime deprecation will now be emitted when `dhparam` is less than
    2048 bits [[`d523eb9c40`](d523eb9]
    [#11447](#11447).

* **URL**
  * The WHATWG URL implementation is now a fully-supported Node.js API
    [[`d080ead0f9`](d080ead]
    [#12710](#12710).

* **Util**
  * `Symbol` keys are now displayed by default when using `util.inspect()`
    [[`5bfd13b81e`](5bfd13b]
    [#9726](#9726).
  * `toJSON` errors will be thrown when formatting `%j`
    [[`455e6f1dd8`](455e6f1]
    [#11708](#11708).
  * Convert `inspect.styles` and `inspect.colors` to prototype-less objects
    [[`aab0d202f8`](aab0d20]
    [#11624](#11624).
  * The new `util.promisify()` API has been added
    [[`99da8e8e02`](99da8e8]
    [#12442](#12442).

* **Zlib**
  * Support `Uint8Array` in Zlib convenience methods
    [[`91383e47fd`](91383e4]
    [#12001](#12001).
  * Zlib errors now use `RangeError` and `TypeError` consistently
    [[`b514bd231e`](b514bd2]
    [#11391](#11391).

jasnell added a commit that referenced this pull request May 30, 2017

2017-05-30, Version 8.0.0 (Current)
* **Async Hooks**
  * The `async_hooks` module has landed in core
    [[`4a7233c178`](4a7233c)]
    [#12892](#12892).

* **Buffer**
  * Using the `--pending-deprecation` flag will cause Node.js to emit a
    deprecation warning when using `new Buffer(num)` or `Buffer(num)`.
    [[`d2d32ea5a2`](d2d32ea)]
    [#11968](#11968).
  * `new Buffer(num)` and `Buffer(num)` will zero-fill new `Buffer` instances
    [[`7eb1b4658e`](7eb1b46)]
    [#12141](#12141).
  * Many `Buffer` methods now accept `Uint8Array` as input
    [[`beca3244e2`](beca324)]
    [#10236](#10236).

* **Child Process**
  * Argument and kill signal validations have been improved
    [[`97a77288ce`](97a7728)]
    [#12348](#12348),
    [[`d75fdd96aa`](d75fdd9)]
    [#10423](#10423).
  * Child Process methods accept `Uint8Array` as input
    [[`627ecee9ed`](627ecee)]
    [#10653](#10653).

* **Console**
  * Error events emitted when using `console` methods are now supressed.
    [[`f18e08d820`](f18e08d)]
    [#9744](#9744).

* **Dependencies**
  * The npm client has been updated to 5.0.0
    [[`3c3b36af0f`](3c3b36a)]
    [#12936](#12936).
  * V8 has been updated to 5.8 with forward ABI stability to 6.0
    [[`60d1aac8d2`](60d1aac)]
    [#12784](#12784).

* **Domains**
  * Native `Promise` instances are now `Domain` aware
    [[`84dabe8373`](84dabe8)]
    [#12489](#12489).

* **Errors**
  * We have started assigning static error codes to errors generated by Node.js.
    This has been done through multiple commits and is still a work in
    progress.

* **File System**
  * The utility class `fs.SyncWriteStream` has been deprecated
    [[`7a55e34ef4`](7a55e34)]
    [#10467](#10467).
  * The deprecated `fs.read()` string interface has been removed
    [[`3c2a9361ff`](3c2a936)]
    [#9683](#9683).

* **HTTP**
  * Improved support for userland implemented Agents
    [[`90403dd1d0`](90403dd)]
    [#11567](#11567).
  * Outgoing Cookie headers are concatenated into a single string
    [[`d3480776c7`](d348077)]
    [#11259](#11259).
  * The `httpResponse.writeHeader()` method has been deprecated
    [[`fb71ba4921`](fb71ba4)]
    [#11355](#11355).
  * New methods for accessing HTTP headers have been added to `OutgoingMessage`
    [[`3e6f1032a4`](3e6f103)]
    [#10805](#10805).

* **Lib**
  * All deprecation messages have been assigned static identifiers
    [[`5de3cf099c`](5de3cf0)]
    [#10116](#10116).
  * The legacy `linkedlist` module has been removed
    [[`84a23391f6`](84a2339)]
    [#12113](#12113).

* **N-API**
  * Experimental support for the new N-API API has been added
    [[`56e881d0b0`](56e881d)]
    [#11975](#11975).

* **Process**
  * Process warning output can be redirected to a file using the
    `--redirect-warnings` command-line argument
    [[`03e89b3ff2`](03e89b3)]
    [#10116](#10116).
  * Process warnings may now include additional detail
    [[`dd20e68b0f`](dd20e68)]
    [#12725](#12725).

* **REPL**
  * REPL magic mode has been deprecated
    [[`3f27f02da0`](3f27f02)]
    [#11599](#11599).

* **Src**
  * `NODE_MODULE_VERSION` has been updated to 57
    (ec7cbaf)]
    [#12995](#12995).
  * Add `--pending-deprecation` command-line argument and
    `NODE_PENDING_DEPRECATION` environment variable
    [[`a16b570f8c`](a16b570)]
    [#11968](#11968).
  * The `--debug` command-line argument has been deprecated. Note that
    using `--debug` will enable the *new* Inspector-based debug protocol
    as the legacy Debugger protocol previously used by Node.js has been
    removed. [[`010f864426`](010f864)]
    [#12949](#12949).
  * Throw when the `-c` and `-e` command-line arguments are used at the same
    time [[`a5f91ab230`](a5f91ab)]
    [#11689](#11689).
  * Throw when the `--use-bundled-ca` and `--use-openssl-ca` command-line
    arguments are used at the same time.
    [[`8a7db9d4b5`](8a7db9d)]
    [#12087](#12087).

* **Stream**
  * `Stream` now supports `destroy()` and `_destroy()` APIs
    [[`b6e1d22fa6`](b6e1d22)]
    [#12925](#12925).
  * `Stream` now supports the `_final()` API
    [[`07c7f198db`](07c7f19)]
    [#12828](#12828).

* **TLS**
  * The `rejectUnauthorized` option now defaults to `true`
    [[`348cc80a3c`](348cc80)]
    [#5923](#5923).
  * The `tls.createSecurePair()` API now emits a runtime deprecation
    [[`a2ae08999b`](a2ae089)]
    [#11349](#11349).
  * A runtime deprecation will now be emitted when `dhparam` is less than
    2048 bits [[`d523eb9c40`](d523eb9)]
    [#11447](#11447).

* **URL**
  * The WHATWG URL implementation is now a fully-supported Node.js API
    [[`d080ead0f9`](d080ead)]
    [#12710](#12710).

* **Util**
  * `Symbol` keys are now displayed by default when using `util.inspect()`
    [[`5bfd13b81e`](5bfd13b)]
    [#9726](#9726).
  * `toJSON` errors will be thrown when formatting `%j`
    [[`455e6f1dd8`](455e6f1)]
    [#11708](#11708).
  * Convert `inspect.styles` and `inspect.colors` to prototype-less objects
    [[`aab0d202f8`](aab0d20)]
    [#11624](#11624).
  * The new `util.promisify()` API has been added
    [[`99da8e8e02`](99da8e8)]
    [#12442](#12442).

* **Zlib**
  * Support `Uint8Array` in Zlib convenience methods
    [[`91383e47fd`](91383e4)]
    [#12001](#12001).
  * Zlib errors now use `RangeError` and `TypeError` consistently
    [[`b514bd231e`](b514bd2)]
    [#11391](#11391).
@ljharb

This comment has been minimized.

Show comment
Hide comment
@ljharb

ljharb May 30, 2017

I just published https://www.npmjs.com/package/util.promisify (with code largely copy/pasted from this PR, with permission from @addaleax) for those interested.

ljharb commented May 30, 2017

I just published https://www.npmjs.com/package/util.promisify (with code largely copy/pasted from this PR, with permission from @addaleax) for those interested.

@divyenduz divyenduz referenced this pull request in NodeRedis/node_redis Jun 16, 2017

Open

Support Promise #864

gibfahn added a commit to gibfahn/node that referenced this pull request Jun 17, 2017

test: introduce `common.crashOnUnhandledRejection`
Ref: nodejs#12442
PR-URL: nodejs#12489
Backport-PR-URL: nodejs#13103
Reviewed-By: Matthew Loring <mattloring@google.com>
Reviewed-By: Julien Gilli <jgilli@nodejs.org>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

gibfahn added a commit that referenced this pull request Jun 20, 2017

test: introduce `common.crashOnUnhandledRejection`
Ref: #12442
PR-URL: #12489
Backport-PR-URL: #13103
Reviewed-By: Matthew Loring <mattloring@google.com>
Reviewed-By: Julien Gilli <jgilli@nodejs.org>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>

MylesBorins added a commit that referenced this pull request Jul 11, 2017

test: introduce `common.crashOnUnhandledRejection`
Ref: #12442
PR-URL: #12489
Backport-PR-URL: #13103
Reviewed-By: Matthew Loring <mattloring@google.com>
Reviewed-By: Julien Gilli <jgilli@nodejs.org>
Reviewed-By: Benjamin Gruenbaum <benjamingr@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
+ promiseResolve(promise, values[0]);
+ }
+ });
+ } catch (err) {

This comment has been minimized.

@syrnick

syrnick Jul 18, 2017

This catch may accidentally catch errors thrown from promiseReject if orig.call happened to be synchronous. E.g. the value was cached in memory and didn't need a remote lookup. promiseReject on line 264 will be a no-op in that case.

Ideally if the execution hit line 253 and then 264, it should re-throw the error instead of no-oping. At least it could log a warning.

@syrnick

syrnick Jul 18, 2017

This catch may accidentally catch errors thrown from promiseReject if orig.call happened to be synchronous. E.g. the value was cached in memory and didn't need a remote lookup. promiseReject on line 264 will be a no-op in that case.

Ideally if the execution hit line 253 and then 264, it should re-throw the error instead of no-oping. At least it could log a warning.

This comment has been minimized.

@ljharb

ljharb Jul 18, 2017

The existing way is definitely better; a function that returns a promise should never throw, only return a rejected promise.

@ljharb

ljharb Jul 18, 2017

The existing way is definitely better; a function that returns a promise should never throw, only return a rejected promise.

This comment has been minimized.

@benjamingr

benjamingr Jul 18, 2017

Member

@syrnick can you please open an issue about it?

@benjamingr

benjamingr Jul 18, 2017

Member

@syrnick can you please open an issue about it?

This comment has been minimized.

@ljharb

ljharb Jul 18, 2017

(also, since a promise can only represent one value; new Promise((resolve, reject) => { reject(1); reject(2); }) is supposed to have the second rejection be a noop, and does not throw the 2, so it'd be important for util.promisify to maintain parity)

@ljharb

ljharb Jul 18, 2017

(also, since a promise can only represent one value; new Promise((resolve, reject) => { reject(1); reject(2); }) is supposed to have the second rejection be a noop, and does not throw the 2, so it'd be important for util.promisify to maintain parity)

@benjamingr benjamingr referenced this pull request in nodejs/promises Aug 16, 2017

Open

Promise Performance Meeting #31

@benjamingr benjamingr referenced this pull request in nodejs/CTC Sep 1, 2017

Closed

Allow passing objects to `util.promisify` #174

@merisbahti merisbahti referenced this pull request in merisbahti/promiser.js Oct 19, 2017

Open

Just a comment #1

@@ -217,3 +219,62 @@ module.exports = exports = {
// default isEncoding implementation, just in case userland overrides it.
kIsEncodingSymbol: Symbol('node.isEncoding')
};
+
+const kCustomPromisifiedSymbol = Symbol('util.promisify.custom');
+const kCustomPromisifyArgsSymbol = Symbol('customPromisifyArgs');

This comment has been minimized.

@syrnick

syrnick Jan 31, 2018

What's the motivation for keeping this private? It's obviously useful in a number of places.

@syrnick

syrnick Jan 31, 2018

What's the motivation for keeping this private? It's obviously useful in a number of places.

This comment has been minimized.

@syrnick

syrnick Jan 31, 2018

but that's still on internal/util, not accessible to user code. The other one(kCustomPromisifiedSymbol) is available as util.promisify.custom.

@syrnick

syrnick Jan 31, 2018

but that's still on internal/util, not accessible to user code. The other one(kCustomPromisifiedSymbol) is available as util.promisify.custom.

This comment has been minimized.

gabrielschulhof added a commit to gabrielschulhof/node that referenced this pull request Mar 12, 2018

2017-05-30, Version 8.0.0 (Current)
* **Async Hooks**
  * The `async_hooks` module has landed in core
    [[`4a7233c178`](nodejs@4a7233c)]
    [#12892](nodejs#12892).

* **Buffer**
  * Using the `--pending-deprecation` flag will cause Node.js to emit a
    deprecation warning when using `new Buffer(num)` or `Buffer(num)`.
    [[`d2d32ea5a2`](nodejs@d2d32ea)]
    [#11968](nodejs#11968).
  * `new Buffer(num)` and `Buffer(num)` will zero-fill new `Buffer` instances
    [[`7eb1b4658e`](nodejs@7eb1b46)]
    [#12141](nodejs#12141).
  * Many `Buffer` methods now accept `Uint8Array` as input
    [[`beca3244e2`](nodejs@beca324)]
    [#10236](nodejs#10236).

* **Child Process**
  * Argument and kill signal validations have been improved
    [[`97a77288ce`](nodejs@97a7728)]
    [#12348](nodejs#12348),
    [[`d75fdd96aa`](nodejs@d75fdd9)]
    [#10423](nodejs#10423).
  * Child Process methods accept `Uint8Array` as input
    [[`627ecee9ed`](nodejs@627ecee)]
    [#10653](nodejs#10653).

* **Console**
  * Error events emitted when using `console` methods are now supressed.
    [[`f18e08d820`](nodejs@f18e08d)]
    [#9744](nodejs#9744).

* **Dependencies**
  * The npm client has been updated to 5.0.0
    [[`3c3b36af0f`](nodejs@3c3b36a)]
    [#12936](nodejs#12936).
  * V8 has been updated to 5.8 with forward ABI stability to 6.0
    [[`60d1aac8d2`](nodejs@60d1aac)]
    [#12784](nodejs#12784).

* **Domains**
  * Native `Promise` instances are now `Domain` aware
    [[`84dabe8373`](nodejs@84dabe8)]
    [#12489](nodejs#12489).

* **Errors**
  * We have started assigning static error codes to errors generated by Node.js.
    This has been done through multiple commits and is still a work in
    progress.

* **File System**
  * The utility class `fs.SyncWriteStream` has been deprecated
    [[`7a55e34ef4`](nodejs@7a55e34)]
    [#10467](nodejs#10467).
  * The deprecated `fs.read()` string interface has been removed
    [[`3c2a9361ff`](nodejs@3c2a936)]
    [#9683](nodejs#9683).

* **HTTP**
  * Improved support for userland implemented Agents
    [[`90403dd1d0`](nodejs@90403dd)]
    [#11567](nodejs#11567).
  * Outgoing Cookie headers are concatenated into a single string
    [[`d3480776c7`](nodejs@d348077)]
    [#11259](nodejs#11259).
  * The `httpResponse.writeHeader()` method has been deprecated
    [[`fb71ba4921`](nodejs@fb71ba4)]
    [#11355](nodejs#11355).
  * New methods for accessing HTTP headers have been added to `OutgoingMessage`
    [[`3e6f1032a4`](nodejs@3e6f103)]
    [#10805](nodejs#10805).

* **Lib**
  * All deprecation messages have been assigned static identifiers
    [[`5de3cf099c`](nodejs@5de3cf0)]
    [#10116](nodejs#10116).
  * The legacy `linkedlist` module has been removed
    [[`84a23391f6`](nodejs@84a2339)]
    [#12113](nodejs#12113).

* **N-API**
  * Experimental support for the new N-API API has been added
    [[`56e881d0b0`](nodejs@56e881d)]
    [#11975](nodejs#11975).

* **Process**
  * Process warning output can be redirected to a file using the
    `--redirect-warnings` command-line argument
    [[`03e89b3ff2`](nodejs@03e89b3)]
    [#10116](nodejs#10116).
  * Process warnings may now include additional detail
    [[`dd20e68b0f`](nodejs@dd20e68)]
    [#12725](nodejs#12725).

* **REPL**
  * REPL magic mode has been deprecated
    [[`3f27f02da0`](nodejs@3f27f02)]
    [#11599](nodejs#11599).

* **Src**
  * `NODE_MODULE_VERSION` has been updated to 57
    (nodejs@ec7cbaf)]
    [#12995](nodejs#12995).
  * Add `--pending-deprecation` command-line argument and
    `NODE_PENDING_DEPRECATION` environment variable
    [[`a16b570f8c`](nodejs@a16b570)]
    [#11968](nodejs#11968).
  * The `--debug` command-line argument has been deprecated. Note that
    using `--debug` will enable the *new* Inspector-based debug protocol
    as the legacy Debugger protocol previously used by Node.js has been
    removed. [[`010f864426`](nodejs@010f864)]
    [#12949](nodejs#12949).
  * Throw when the `-c` and `-e` command-line arguments are used at the same
    time [[`a5f91ab230`](nodejs@a5f91ab)]
    [#11689](nodejs#11689).
  * Throw when the `--use-bundled-ca` and `--use-openssl-ca` command-line
    arguments are used at the same time.
    [[`8a7db9d4b5`](nodejs@8a7db9d)]
    [#12087](nodejs#12087).

* **Stream**
  * `Stream` now supports `destroy()` and `_destroy()` APIs
    [[`b6e1d22fa6`](nodejs@b6e1d22)]
    [#12925](nodejs#12925).
  * `Stream` now supports the `_final()` API
    [[`07c7f198db`](nodejs@07c7f19)]
    [#12828](nodejs#12828).

* **TLS**
  * The `rejectUnauthorized` option now defaults to `true`
    [[`348cc80a3c`](nodejs@348cc80)]
    [#5923](nodejs#5923).
  * The `tls.createSecurePair()` API now emits a runtime deprecation
    [[`a2ae08999b`](nodejs@a2ae089)]
    [#11349](nodejs#11349).
  * A runtime deprecation will now be emitted when `dhparam` is less than
    2048 bits [[`d523eb9c40`](nodejs@d523eb9)]
    [#11447](nodejs#11447).

* **URL**
  * The WHATWG URL implementation is now a fully-supported Node.js API
    [[`d080ead0f9`](nodejs@d080ead)]
    [#12710](nodejs#12710).

* **Util**
  * `Symbol` keys are now displayed by default when using `util.inspect()`
    [[`5bfd13b81e`](nodejs@5bfd13b)]
    [#9726](nodejs#9726).
  * `toJSON` errors will be thrown when formatting `%j`
    [[`455e6f1dd8`](nodejs@455e6f1)]
    [#11708](nodejs#11708).
  * Convert `inspect.styles` and `inspect.colors` to prototype-less objects
    [[`aab0d202f8`](nodejs@aab0d20)]
    [#11624](nodejs#11624).
  * The new `util.promisify()` API has been added
    [[`99da8e8e02`](nodejs@99da8e8)]
    [#12442](nodejs#12442).

* **Zlib**
  * Support `Uint8Array` in Zlib convenience methods
    [[`91383e47fd`](nodejs@91383e4)]
    [#12001](nodejs#12001).
  * Zlib errors now use `RangeError` and `TypeError` consistently
    [[`b514bd231e`](nodejs@b514bd2)]
    [#11391](nodejs#11391).

This applies parts of 43e4efd that are
relevant to N-API.

gabrielschulhof added a commit to gabrielschulhof/node that referenced this pull request Mar 15, 2018

2017-05-30, Version 8.0.0 (Current)
* **Async Hooks**
  * The `async_hooks` module has landed in core
    [[`4a7233c178`](nodejs@4a7233c]
    [#12892](nodejs#12892).

* **Buffer**
  * Using the `--pending-deprecation` flag will cause Node.js to emit a
    deprecation warning when using `new Buffer(num)` or `Buffer(num)`.
    [[`d2d32ea5a2`](nodejs@d2d32ea]
    [#11968](nodejs#11968).
  * `new Buffer(num)` and `Buffer(num)` will zero-fill new `Buffer` instances
    [[`7eb1b4658e`](nodejs@7eb1b46]
    [#12141](nodejs#12141).
  * Many `Buffer` methods now accept `Uint8Array` as input
    [[`beca3244e2`](nodejs@beca324]
    [#10236](nodejs#10236).

* **Child Process**
  * Argument and kill signal validations have been improved
    [[`97a77288ce`](nodejs@97a7728]
    [#12348](nodejs#12348),
    [[`d75fdd96aa`](nodejs@d75fdd9]
    [#10423](nodejs#10423).
  * Child Process methods accept `Uint8Array` as input
    [[`627ecee9ed`](nodejs@627ecee]
    [#10653](nodejs#10653).

* **Console**
  * Error events emitted when using `console` methods are now supressed.
    [[`f18e08d820`](nodejs@f18e08d]
    [#9744](nodejs#9744).

* **Dependencies**
  * The npm client has been updated to 5.0.0
    [[`3c3b36af0f`](nodejs@3c3b36a]
    [#12936](nodejs#12936).
  * V8 has been updated to 5.8 with forward ABI stability to 6.0
    [[`60d1aac8d2`](nodejs@60d1aac]
    [#12784](nodejs#12784).

* **Domains**
  * Native `Promise` instances are now `Domain` aware
    [[`84dabe8373`](nodejs@84dabe8]
    [#12489](nodejs#12489).

* **Errors**
  * We have started assigning static error codes to errors generated by Node.js.
    This has been done through multiple commits and is still a work in
    progress.

* **File System**
  * The utility class `fs.SyncWriteStream` has been deprecated
    [[`7a55e34ef4`](nodejs@7a55e34]
    [#10467](nodejs#10467).
  * The deprecated `fs.read()` string interface has been removed
    [[`3c2a9361ff`](nodejs@3c2a936]
    [#9683](nodejs#9683).

* **HTTP**
  * Improved support for userland implemented Agents
    [[`90403dd1d0`](nodejs@90403dd]
    [#11567](nodejs#11567).
  * Outgoing Cookie headers are concatenated into a single string
    [[`d3480776c7`](nodejs@d348077]
    [#11259](nodejs#11259).
  * The `httpResponse.writeHeader()` method has been deprecated
    [[`fb71ba4921`](nodejs@fb71ba4]
    [#11355](nodejs#11355).
  * New methods for accessing HTTP headers have been added to `OutgoingMessage`
    [[`3e6f1032a4`](nodejs@3e6f103]
    [#10805](nodejs#10805).

* **Lib**
  * All deprecation messages have been assigned static identifiers
    [[`5de3cf099c`](