-
Notifications
You must be signed in to change notification settings - Fork 111
Use a promise chain instead? #56
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
Comments
This wouldn't be able to be synchronous. |
|
No, it does not. It makes it appear synchronous, but it is not. |
When writing synchronous code this makes no difference. If you think otherwise, then please give an example. P.S. The best value that my approach brings is to be able to mix synchronous and asynchronous code without extra effort, which is one of the most important features in the modern JavaScript. |
It absolutely makes a difference. Polyfills need to happen synchronously, for one - operations that happen on DOM NodeLists would need to be synchronous to ensure that nothing else was mutating the DOM out from under it, etc. Note that I'm not talking about the code in the line you're awaiting - it's that because |
One typically doesn't use asynchronous functions when modifying DOM. But this is just one specific task, not worth consideration in the context of extending JavaScript syntax. Also, you can use synchronous chain like this: let result = chain('hello', [doubleSay, capitalize, exclaim]); with function chain(value, list) {
list.forEach(a => {
value = a(value);
});
return value;
} |
FWIW, is there support for pipelining a chain of async functions? Or mixing sync & async? e.g. data |> formatForRequest
|> await makeRequest
|> formatResponse
|> appendResults |
The same applies to any mutation, not just the DOM - it's absolutely a core language use case. Your chain example doesn't preserve the receiver; using .bind there would not be ergonomic. A synchronous operator is necessary here. If promises were sufficient, this proposal would indeed not need to exist - but they are not. |
@mAAdhaTTah Unfortunately this will not do what you hope it would do. |
@littledan Is it worth amending the proposal to include mixed sync/async pipelining? I don't know if the syntax suggested above has complexities I'm not seeing, but the current pipeline doesn't easily support async without manually juggling the promises. Perhaps this also could / should come in a future proposal, a la async iterators. |
My bad, that's duplicated by #53. |
It doesn't even have to be that complicated, @ljharb. @vitaly-t proposal works in only a handful of cases, whereas the pipe operator would make readable many more. What seems to be left out of this conversation is how deep you go into function composition and what side effects you have. Combine these two, and obviously you can't use a promise chain to compose functions that together make up a single transaction, so you are essentially creating more problems, if you then want to introduce locks and whatnot on what should simply be synchronous code. Furthermore, performance isn't going to be great if you use a promise chain on functions like Or error handling, since you can accidentally catch what you shouldn't have, thus losing the information for a potentially hard to reproduce problem! On top of that, any |
@rsxdalv I believe "doesn't allow for synchronous" is indeed a less complicated way to summarize your complicated comment :-) |
@ljharb I wanted to bridge the gap between "you can't do sync" and "you want to do sync because of DOM manipulation" to more generic cases that everyone will run into. In a way, I think that there still might be some that hit this thread, who might end up shooting themselves in the foot by the proposal of this issue. Though yes, by complicated I meant "specific". I might edit my original comment. |
desugars into
which works so I would assume yes. |
@vitaly-t await doesn't make it synchronous, it creates a new promise where the result of the promise is bound to the new variable.
Can be viewed as
It's the same way All |
Just a quick heads up. If const isThenable = val => val
&& typeof val === 'object'
&& typeof val.then === 'function';
const then = fn => arg =>
isThenable(arg)
? arg.then(fn)
: fn(arg);
// data |> formatForRequest
// |> await makeRequest
// |> formatResponse
// |> appendResults
data
|> formatForRequest
|> makeRequest
|> then(formatResponse)
|> then(appendResults) |
The then function is an interesting suggestion. Seems like the original suggestion of the Promise then method subsuming this proposal is not really realistic, so closing this thread. |
We can also use simple chaining for synchronous tasks by returning the value from each function, just like jquery does it. |
Uh oh!
There was an error while loading. Please reload this page.
You can simply return a promise from each of such functions, and then write the following:
or:
This creates even better code, IMO, because:
.catch
for the error handler is nicer/shorter thantry{}catch(e){}
.then
call.I think the existing ES7 is already verbose enough, and not lacking anything, except ahem, better support for classes, closer to C++.
As a bonus, you can simplify it even further, by implementing a function that takes a random value + a list of functions to do
.then
for each of them.There are already implementations like this in some promise libraries, so you can do:
This also lets you mix together synchronous and asynchronous code, which is priceless.
The text was updated successfully, but these errors were encountered: