-
Notifications
You must be signed in to change notification settings - Fork 11
How promise APIs would look like in core #16
Comments
Thanks for the issue. I will keep this updated with the current state of the proposal as it evolves. |
Cool :-) Some further suggestions:
|
It would also be good to have links to the why behind the proposals, like:
The original top post contained some links to discussions, but now it is more a summary now. The medium post goes into plenty more detail, but I can see it becoming out of date once again. Perhaps consolidating the original post of the PR, the medium post, and the top post here, into one wiki page on this repo, that the WG can keep up to date, and link to the reasonings, then use these individual repo issue threads to facilitate discussions around the particular issues. |
@balupton: Part of the issue with those links into the GitHub issue is that they work, but they take a really long time to load — GitHub appears to load the initial comments quickly, but then pauses on an extra XHR before jumping to the anchor, and that appears to take the bulk of the time. |
I'm +1 on |
@benjamingr: The technical requirements should be pretty straightforward given the way that the promise API is exposed now, but there's significant work to be done in bringing a conversation about such an approach to consensus. I believe this would best be accomplished by a follow-on PR once nodejs/node#5020 is merged (assuming it will be!), to be merged before unflagging, which is the current plan of action. |
@chrisdickinson Could doing multiple PRs mean that each merged PR's API is locked in? That seems to be the risk here. |
@balupton I do not think so — we are working behind a flag, and the next step after the initial PR is merged is to build up a "go / no go" checklist for unflagging. We can (if we so choose) delay unflagging on getting a satisfactory answer to the |
+1 for +1 for error object/ |
Bikeshed: I firmly believe it's safer and more sensible to call this |
@phpnode: Noted, but this can be discussed on the subsequent PR. It's not likely that a |
I agree that it might be contentious but the reason is social not technical, whereas the benefits of using The counter point is that explicitly requiring I don't think it implies that callbacks are invalid, they're not being deprecated, but they are older. |
@phpnode I think that this attitude where callbacks are "older" and promises are "the next API which people should default to using" will not ever get promises into node core. Callbacks were there first so suggesting |
Agree, I'm not suggesting that, and definitely not suggesting |
@phpnode observables would not replace promises but would rather work in areas Node works with streams and event emitters. No one is suggesting replacing all callbacks with observables. Observables and async iterators are the problems of the streams working group - not us :) |
@benjamingr I'm not talking about observables specifically, rather how this kind of disruptive change is accommodated in future - in this case we're talking about promises, maybe next time we'll be talking about something equally disruptive. Observables is just an example. |
If compat ever breaks, which is too early to tell, it could always become |
Tangent comment moved to #10 (comment) |
A completely separate module can be blacklisted so that concerns such as promises ruining existing post-mortem workflows with callbacks can be addressed by simply blacklisting the separate module as people with such concerns already have to do for 3rd party modules. |
I'll echo that. Don't think I'd want to see |
Regarding the surface promise API, the only other suggestion that is not covered is just updating the existing API methods to use promises instead or with callbacks, so no new methods are introduced, just existing methods are updated. This has probably been discussed somewhere, if so would be good to have the conclusion summarised in the first/original post. Update: updated the initial post with the various proposals and their counter arguments |
This was discussed already in the pull request. Namely nodejs/node#5020 (comment) We're also not going to break "fs" or any of the existing modules. |
@chrisdickinson Apologies if I missed it in the PR thread (was hard to track all that). Would you (or someone else) be able to sum up:
|
@benjamingr cheers, I've updated the initial post with the counters so future people know they are ruled out and why |
Seems so. I've updated the top post with the relevant links.
I'm too confused about any difference in benefits between |
Benefits of having
Benfits of having only
|
Hrmm... If
This is a nifty point as another side of this coin is that considering the |
Also:
|
Seems a strange argument as one only needs at least two modules in their entire app where one module uses the promise API and another module uses the callback API, for this to benefit to be negated, which as time goes by will become highly likely. Unless one of the modules (probably the promise API) is specifically blacklisted somehow, which would cause module restrictions which is perhaps undesirable — is such a blacklisting ever likely to occur? |
Perhaps, but I think it follows along with some comments I saw in the original PR:
My own thought:
|
Could it be possible to choose an alternative promise library ? In mongoose, it is possible to pass a constructor that will be used by the package. Default would be to standard promises, but the possibility to do something like Or better (with all alternatives in discussion):
|
@vdeturckheim that was discussed and decided against (I think). Please see the original PR's comments. |
I am in favor of having separate require("promised/*") modules so that the promise oriented porcelain does not get tangled with the underlying modules. The same pattern may one day be called upon to provide a compatibility layer for web streams, e.g., require("web/fs"), which might be both promise oriented and web streams oriented. Regardless, we need to avoid entangling these concerns with the underlying callback and event-emitter oriented design. |
@benjamingr sorry my bad then. |
Keep in mind that using a top level namespace will break anyone using a module named that in the ecosystem, in this case https://www.npmjs.com/package/promised which doesn't seem to be in heavy use. We'd want to talk with the publisher about pulling it and npm about blocking it from being accessible in the future if we go this route. |
@mikeal I've emailed the owner to see if they'd be willing to transfer the package. |
Just to note, that would only be necessary for |
@omsmith Indeed, but given some thought I believe nesting under |
Update: The author of "promised" has transferred ownership to the Node foundation (for @chrisdickinson ) |
I've updated the +1/-1's for the module approach to reflect the concerns with the approach — in short, it will take a lot of intense discussion, and the concrete version of it will spur a lot of debate. Out of the interest of making this process sustainable, the plan of record is to work on getting 5020 merged without a solution for modules, then work to get modules in behind the flag before unflagging in a separate PR. To do otherwise risks the work in nodejs/node#5020 and that we've done here overall, and I'm not comfortable doing that. While I appreciate the summary of potential plans and their merits/demerits, I'd like to propose we make it reflect the following plan of action:
|
@chrisdickinson I am not sure if you saw it in some other thread, but I suggested separate module because such a module can be blacklisted, just like 3rd party promise modules are currently blacklisted by post-mortem users (I assume). |
@petkaantonov Yep — I saw — the problem is that since there are promisified methods on class instances, disallowing access to promise methods via |
@chrisdickinson which methods on which class instances? EDIT: just noticed the notes you put inline on the top comment. I see you mean |
what about "promised/net" that returns "net" while adding promise methods on the first require? |
|
@petkaantonov As I understand it, that would mean either we'd have to copy/re-run the |
yes, thats what promisifyAll does. Having those methods only when a blacklistable module is required rather than all the time is surely better? |
@petkaantonov To clarify, you're suggesting we mutate |
Oh sorry I thought you were familiar with the api. It mutates the prototype (non destructively). |
Proposing this thread to consolidate the various discussions and proposals around "How promise APIs would look like in core." as the original pull request covers more than just that sole issue, making it hard to keep track of what is actually being proposed. Feel free to edit. [CD: Thanks!]
Proposals for current APIs:
Active proposals:
require('fs').readFilePromise
(current PR proposal) +require('fs').promised.readFile
shortcutAdding Core support for Promises node#5020 (comment)
require('fs/promise').readFile
(future PR proposal) (to immediately follow 5020 once landed)Current / unresolved discussions:
require('fs/promise').readFile
initially, orrequire('fs').readFilePromise
initiallyrequire('fs/promise').readFile
initially and perhaps only+1 allows blacklisting How promise APIs would look like in core #16 (comment)[CD: For top level methods, yes, but not for class instance methods. Still best to block promises usingglobal.Promise = null
in all cases.]-1 requires PR to be updated How promise APIs would look like in core #16 (comment)[CD: I am not concerned about changing the PR.]net.Socket#setTimeout
)fs.createReadStream
)promised
is a frontrunner, since we have the name, but this is a potential for bikeshedding)require('fs').readFilePromise
with or withoutrequire('fs').promised.readFile
shortcut initiallypromised
shortcut works for destructuring assign,import x as y
syntax should work for ES2015 modules].require('fs/promise')
then maintaining 3 endpoints that all do the same thing is pain Adding Core support for Promises node#5020 (comment)require('fs').readFilePromise
andrequire('fs').promised.readFile
, why one or the other?Closed proposals:
require('fs').readFile
returns promises only, no support for callback — one API endpoint to maintain, b/c break for everyone, consistent return types, promises are primary and callbacks are eliminated, could provide cleanest forward APIrequire('fs').readFile
returns promise if no callback is provided, if callback is provided do not return promise and use callback — one API endpoint to maintain, performance hit with additional if check, different return types, callbacks or promises become secondary to the otherprocess.send(message[, sendHandle][, callback])
which can have a return value despite having an async callback, changing return value to promise will break b/c with current return valuerequire('fs').readFile
returns promise always, if callback is provided attach it to the promise — one API endpoint to maintain, performance hit for callback users, consistent return types, promises are primary and callbacks become secondaryprocess.send(message[, sendHandle][, callback])
which can have a return value despite having an async callback, changing return value to promise will break b/c with current return valueProposals for error APIs:
Discussion ongoing at #10, summary:
[CD - There may not need to be an error API — it might look like a flag, like
--abort-on-sync-rejection
]Proposals for new APIs:
[CD - these probably will not land in nodejs/node#5020].
util.promised
:util.promised
- Callbacks and async/await #5util.toCallback
:util.toCallback(asyncFn)
- interop of async functions with callbacks. #6The other issue "How to make sure promises don't get in the way of callback users with core support." seems like a sub-topic of "How promise APIs would look like in core". So perhaps that should be consolidated here too. [CD - Promises will be added using a promisify wrapper, without affecting the original function. They should not interfere with callback APIs at all.]
The text was updated successfully, but these errors were encountered: