{"action":"created","issue":{"url":"https://api.github.com/repos/WebReflection/notify-js/issues/1","labels_url":"https://api.github.com/repos/WebReflection/notify-js/issues/1/labels{/name}","comments_url":"https://api.github.com/repos/WebReflection/notify-js/issues/1/comments","events_url":"https://api.github.com/repos/WebReflection/notify-js/issues/1/events","html_url":"https://github.com/WebReflection/notify-js/pull/1","id":101184486,"number":1,"title":"Adds an overload to `when` for returning Promises","user":{"login":"barneycarroll","id":83627,"avatar_url":"https://avatars.githubusercontent.com/u/83627?v=3","gravatar_id":"","url":"https://api.github.com/users/barneycarroll","html_url":"https://github.com/barneycarroll","followers_url":"https://api.github.com/users/barneycarroll/followers","following_url":"https://api.github.com/users/barneycarroll/following{/other_user}","gists_url":"https://api.github.com/users/barneycarroll/gists{/gist_id}","starred_url":"https://api.github.com/users/barneycarroll/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/barneycarroll/subscriptions","organizations_url":"https://api.github.com/users/barneycarroll/orgs","repos_url":"https://api.github.com/users/barneycarroll/repos","events_url":"https://api.github.com/users/barneycarroll/events{/privacy}","received_events_url":"https://api.github.com/users/barneycarroll/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":17,"created_at":"2015-08-15T15:20:55Z","updated_at":"2015-08-16T11:06:51Z","closed_at":"2015-08-15T18:45:50Z","pull_request":{"url":"https://api.github.com/repos/WebReflection/notify-js/pulls/1","html_url":"https://github.com/WebReflection/notify-js/pull/1","diff_url":"https://github.com/WebReflection/notify-js/pull/1.diff","patch_url":"https://github.com/WebReflection/notify-js/pull/1.patch"},"body":"The rationale depends upon ES7's `async` / `await`. The logic is that callback scopes are extra painful when you're dealing with a series of events that might already have occurred, and being able to `await` a notification makes massive sense when it's possible that the code may execute directly (well, not completely, but you get the idea). Basically, you can write code as if the asynchronicity of the notification is immaterial.\r\n\r\n```javascript\r\n// Currently\r\nnotify.when( 'authenticated', userProfile =>\r\n\t// ...App logic\r\n)\r\n\r\n// My proposal: overload `when` to return an actual promise when no callback is provided\r\n// Ugly monkey-patch version:\r\nnotify.when = ( type, callback ) =>\r\n\tcallback\r\n\t\t? when( type, callback )\r\n\t\t: new Promise( success =>\r\n\t\t\twhen( type, success )\r\n\t\t)\r\n\r\n// Using current environments, usage would just add extra cruft and cognitive noise \r\n// Extra confusing \"hang on how promise-like is this?\"\r\nnotify.when( 'authenticated' ).then( userProfile => {\r\n\t// ...App logic\r\n} )\r\n\r\n// But in ES7, this becomes awesome because you can flatten the whole thing to better reflect the sequential model\r\nconst userProfile = await notify.when( 'authenticated' )\r\n\r\n// ...App logic\r\n```"},"comment":{"url":"https://api.github.com/repos/WebReflection/notify-js/issues/comments/131525230","html_url":"https://github.com/WebReflection/notify-js/pull/1#issuecomment-131525230","issue_url":"https://api.github.com/repos/WebReflection/notify-js/issues/1","id":131525230,"user":{"login":"WebReflection","id":85749,"avatar_url":"https://avatars.githubusercontent.com/u/85749?v=3","gravatar_id":"","url":"https://api.github.com/users/WebReflection","html_url":"https://github.com/WebReflection","followers_url":"https://api.github.com/users/WebReflection/followers","following_url":"https://api.github.com/users/WebReflection/following{/other_user}","gists_url":"https://api.github.com/users/WebReflection/gists{/gist_id}","starred_url":"https://api.github.com/users/WebReflection/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/WebReflection/subscriptions","organizations_url":"https://api.github.com/users/WebReflection/orgs","repos_url":"https://api.github.com/users/WebReflection/repos","events_url":"https://api.github.com/users/WebReflection/events{/privacy}","received_events_url":"https://api.github.com/users/WebReflection/received_events","type":"User","site_admin":false},"created_at":"2015-08-16T11:06:51Z","updated_at":"2015-08-16T11:06:51Z","body":"> What does await notify.when('event', callback); do?\r\nnothing, you would never write that indeed. You want a Promise? You don't pass the callback: it's straight forward!\r\n\r\n\r\n> What does notify.when('event') do in an environment without Promise support?\r\nit throws, because if you want a Promise, you must be sure your environment supports them. This utility does not provide the Polyfill, it's your responsibility to define Promise as dependency.\r\n\r\nIndeed, if you write code based on  Promises and your env doesn't support Promises, you are doing it wrong. Unless you know what you are doing, otherwise fail safe, fail fast, fail reasonably.\r\n\r\nSilent failure? **Now that is a problem**!\r\n\r\n\r\n\r\n> await never does anything meaningful, and failing to provide a callback never does anything meaningful (perhaps it should have thrown in that case, or now, but that isn't really relevant to this topic).\r\n\r\nNo, you have a method that does exactly what it says it does if you pass a callback or you don't. A method that maybe returns a Promise if you asked for it and silently fail otherwise is the worst from every world.\r\n\r\n\r\n>  it just silently fails without Promise, and works when it is present \r\n`if (Promise && !callback) {` breaks if Promise is not available 'cause if not defined `if (NotDefined` breaks. However, that code didn't land here.\r\n\r\n\r\n>  I now see the code in your comment which is different from that in the repo, and does indeedresolve some of these issues\r\nYou should have read my comments and the snippet I have posted. This gave me an indication you are randomly ranting without paying attention. Why is that?\r\n\r\n\r\n> pivoting only on environment support\r\nit makes the code non trustable by developer intent. If you want a Promise, you have a way to have it. If that is not supported, but you are writing Promises based code, you need to solve the optional  dependency upfront by your own. This code will never ship  with ES6 features because **it's not needed**.  It's a nice to have, that was this overload proposal about, and it is there.\r\n\r\nIn case it's not clear: **if you need a Promise,  you don't pass the callback** because that is branching behavior,  making the intent impossible to understand from  the method code (I don't know if the returned Promise will ever be used) and for the reader ( two conflicting/ravcing functions at resolution time )\r\n\r\n> Now that you've added that, you've already promoted \"patterns conflict\"\r\n\r\nNow that I have overloaded the method, after discussing it with @barneycarroll it is clear by simply reading a piece of code what the developer needed ( a Promise or not? ) and what the method will return accordingly with the way you invoked it.\r\n\r\nSo, re-quoting myself:\r\n\r\n> good API doesn't mean what you would write on a book, it means how it makes your life easier/better daily. If it's both even better\r\n\r\nHere we are making the API works everywhere, without needing a mandatory dependency like ES6 Promise is, keeping it simple, improving its usability for the past, the present, and the future.\r\n\r\n\r\n> so be it\r\n\r\nI hope so."}}