Promises for dummies


  • kills Dumbledore

    I'm doing a Microsoft training course on HTML/JS/CSS development, and it's touched on promises.

    I'm having the exact same problem as every time I try to learn about promises, where it seems like every tutorial, no matter how "beginner", seems to assume some knowledge I don't have. Either that or I just have a huge mental block over whatever something that's too obvious to mention.

    The training video recommended http://codefoster.com/usingpromises/ for more information. It's mostly the same as what was in the video and again I'm lost.

    Representative sample:

    In Windows 8 JavaScript development we have the WinJS.Promise. You create it like this…

    new WinJS.Promise(function(c,e,p) {
       //function body
    });
    

    The c, e, and p are parameters that are themselves functions. Within the function body, then, I can actually call c() when I want to complete the promise, call e() when I want to report an errant case, or call p() when I want to report progress.

    Study this method I wrote that makes sure a file exists and if it doesn’t then it creates it…

    function assureFileAsync() {
       return new WinJS.Promise(function (c, e, p) {
           if (fileExists("applicationData.json"))
               c();
           else
               appdata.roamingFolder.createFileAsync("applicationData.json")
                   .then(function (file) {
                       return Windows.Storage.FileIO.writeTextAsync(
                           file, JSON.stringify(starterData)
                       );
                   })
                   .done(function () { c(); });
       });
    }
    

    So c,e and p are functions. Fine. Do I define them? Do I have to pass them in when I call the promise? How does the progress one report progress? Does it take a numeric argument for percentage complete or something? None of this seems to be explained. Maybe a lot of this is specific to the WinJS version of promises? I don't know

    Is there any guide out there that actually explains this stuff rather than saying you need error and progress functions then not mentioning them again?



  • @Jaloopa Looks like bad parameter names to me. c is probably the completed callback, p is probably a progress callback, and e is probably an error callback. I've never used WinJS before.


  • Considered Harmful

    I don't know about a guide, but I'm more than willing to walk you through Promise usage.

    I sent you a PM.


    Filed under: IM, PM, DM... What are the kids calling them these days?


  • FoxDev

    @Jaloopa said in Promises for dummies:

    So c,e and p are functions.

    they're also parameters. you're good to not define them.

    the "standard" names for the parameters in javascript when you're not being a prick and using single letter symbol names are: resolve, reject, and progress

    you should not rely on progress being defined in general, that's not part of the Promises/A+ spec. WinJS uses it but other promise libraries might not.

    you will call resolve() once when you successfully complete the promise, if you are providing a "return value" you may pass it as a single value as resolve(value) if you need to provide multiple values to the promise chain you must use an array or object to contain them.

    you will call reject(err) once when you unsuccessfully complete the promise. You should provide a single parameter to the function call of type Error

    the signature and usage of progress() is non standard and will vary from promise library to promise library, if it is supported at all. In general you call this function as often as you please to report progress through the promise. the parameters are generally, but not always, defined by the programmer to be whatever they find useful to report.


  • Considered Harmful

    @error said in Promises for dummies:

    I don't know about a guide,

    I take it back, here is the article that introduced me to the concept.


  • Considered Harmful

    Someone should really make a site that's a cross of jsfiddle, google docs, and a simple chat client.


  • kills Dumbledore

    @accalia said in Promises for dummies:

    the "standard" names for the parameters in javascript when you're not being a prick and using single letter symbol names are: resolve, reject, and progress

    Yeah, he does explain that it's complete, error and progress, just no real context as to what they are and what you do with them

    @accalia said in Promises for dummies:

    you will call resolve() once when you successfully complete the promise, if you are providing a "return value" you may pass it as a single value as resolve(value) if you need to provide multiple values to the promise chain you must use an array or object to contain them.

    So if I'm using a promise from some library I need to know what sort of object would be returned by the promise in order to be able to call methods or access properties? Is it effectively what gets called when I do a .then on the promise?

    @error said in Promises for dummies:

    I take it back, here is the article that introduced me to the concept.

    Cool, I'll have a read of that


  • Grade A Premium Asshole

    @error said in Promises for dummies:

    Someone should really make a site that's a cross of jsfiddle, google docs, and a simple chat client.


  • FoxDev

    @Jaloopa said in Promises for dummies:

    So if I'm using a promise from some library I need to know what sort of object would be returned by the promise in order to be able to call methods or access properties? Is it effectively what gets called when I do a .then on the promise?

    yeah. calling .then(onResolve) on a promise says "when the promise resolves call this function and pass the resolved value as the first (and only) parameter. if your onResolve function returns a non-promise value it will be promoted to a promise and returned from the then(onResolve) call so you can continue chaining promises together. If your onResolve returns a promise then the promise is returned instead, also allowing for more chaining.

    you can also call then(undefined, onReject) or .catch(onReject) to register a rejection handler into the chain to do cleanup or fallback behavior. onReject() has the same semantics as onResolve

    you can also call .then(onResolve, onReject) to register both handlers to a single point in the promise chain, only one of onResolve or onReject will be called depending on how the prior promise completes.


  • ♿ (Parody)

    @accalia said in Promises for dummies:

    you will call...

    And I presume you should really write them as:

    return resolve();
    
    return reject(err);
    

    So that no processing happens later on (eventually control will come back to your function otherwise. I've been bitten by that in other asynchronous js code.


  • FoxDev

    @boomzilla said in Promises for dummies:

    @accalia said in Promises for dummies:

    you will call...

    And I presume you should really write them as:

    return resolve();
    
    return reject(err);
    

    So that no processing happens later on (eventually control will come back to your function otherwise. I've been bitten by that in other asynchronous js code.

    this is correct.

    you don't have to return the resolve/reject call (the functions return undefined) but it's considered a bad habit not to.


  • FoxDev

    @Polygeekery said in Promises for dummies:

    @error said in Promises for dummies:

    Someone should really make a site that's a cross of jsfiddle, google docs, and a simple chat client.

    props to cloud9

    99.6% of sockbot was and is developed ther


  • ♿ (Parody)

    @accalia said in Promises for dummies:

    you don't have to return the resolve/reject call (the functions return undefined) but it's considered a bad habit not to.

    Yeah, I've gotten lazy sometimes when it's at the "end" and resuming control would implicitly return right at the end, but I've also gotten lazy and created errors that to my mind are similar to not using braces for your if statements.


  • I survived the hour long Uno hand

    @Jaloopa said in Promises for dummies:

    if I'm using a promise from some library I need to know what sort of object would be returned by the promise

    A promise can return absolutely anything a function can. Similar to CPS, it will "return" the value by calling a callback. The only real difference is instead of calling

    doSomething(foo, bar, function (result) {
        //do something with result
    })
    

    You write it

    doSomething(foo, bar).then(function(result) {
    
    });
    

    Which makes for a much flatter call stack:

    doSomething(foo, bar).then(function(result) {
        return doSomethingElse(result);
    }).then(function(secondResult) {
        //something
    });
    

    instead of CPS:

    doSomething(foo, bar, function (result) {
        doSomethingElse(result, function(secondResult) {
            //something
        });
    });
    

    A promise is a wrapper around a function. Therefore, when you construct one, you hand it a function.

    The promise chain will halt execution if an error result is returned. Therefore, it needs to know when you've reached an error state you cannot recover from. Therefore, you are handed two functions to work with: one to return a value on success, and one to signal an error state. Your library apparently uses a third, but I don't usually work with that.


  • Considered Harmful

    @accalia said in Promises for dummies:

    .catch(onReject)

    Stupid browsers have issues with method names that are keywords.

    I've had to write promise[ 'catch' ](...), but prefer .then( null, function() {} )


  • Considered Harmful

    @Polygeekery said in Promises for dummies:

    @error said in Promises for dummies:

    Someone should really make a site that's a cross of jsfiddle, google docs, and a simple chat client.

    :wtf: have I been doing with my life?


  • Considered Harmful

    @error said in Promises for dummies:

    @Polygeekery said in Promises for dummies:

    @error said in Promises for dummies:

    Someone should really make a site that's a cross of jsfiddle, google docs, and a simple chat client.

    :wtf: have I been doing with my life?

    They want my 💳 for a free account. :doing_it_wrong:


  • Winner of the 2016 Presidential Election

    @accalia said in Promises for dummies:

    the "standard" names for the parameters in javascript when you're not being a prick and using single letter symbol names are: resolve, reject, and progress

    Are you sure? Those names suck. I'd rather use success and failure.



  • @pydsigner
    Those names only make sense if success indicates that you torpedoed the user's request and that failure means you weren't able to find any way to prevent it.


  • FoxDev

    @pydsigner said in Promises for dummies:

    @accalia said in Promises for dummies:

    the "standard" names for the parameters in javascript when you're not being a prick and using single letter symbol names are: resolve, reject, and progress

    Are you sure? Those names suck. I'd rather use success and failure.

    yes, i am sure.

    however it is JS hence the scarequotes.


  • Considered Harmful

    @pydsigner said in Promises for dummies:

    @accalia said in Promises for dummies:

    the "standard" names for the parameters in javascript when you're not being a prick and using single letter symbol names are: resolve, reject, and progress

    Are you sure? Those names suck. I'd rather use success and failure.

    Those terms may create a false implication for certain usages of the API.

    :hanzo:d



  • @boomzilla said in Promises for dummies:

    Yeah, I've gotten lazy sometimes when it's at the "end" and resuming control would implicitly return right at the end, but I've also gotten lazy and created errors that to my mind are similar to not using braces for your if statements.

    Given that "lazy" is the operative word when it comes to promises, that seems appropriate.

    I've seen some absurd ways of implementing a continuation before, but seriously, Microsoft?

    Oh, wait, Microsoft didn't come up with this shitshow, they just implemented it. Good on them, I guess.


  • Winner of the 2016 Presidential Election

    @izzion said in Promises for dummies:

    @pydsigner
    Those names only make sense if success indicates that you torpedoed the user's request and that failure means you weren't able to find any way to prevent it.

    I think I'm :woosh:ing right now.



  • I basically proposed defining true as false and false as true. I just left off the 🚎 from the end of my statement :p

    Also, dammit emoji autocomplete, I do not want to ship a 📦 every time I stick my tongue out.


  • Considered Harmful

    @izzion said in Promises for dummies:

    I basically proposed defining true as false and false as true.

    VB uses 0 for False and -1 for True

    Spoiler It's because it treats operators as bitwise, not logical. So `True` is `Not False`, which is `~0`, which is `11111111111111111111111111111111`, which is -1.

    INB4 VB is not logical.

    Filed under: Yet another Markdown :wtf:


  • Discourse touched me in a no-no place

    @ScholRLEA said in Promises for dummies:

    Given that "lazy" is the operative word when it comes to promises, that seems appropriate.

    It all feels like a rather nasty poor-man's coroutine to me, with all the complexity of needing to do non-trivial closure management and so on, but a much more complicated syntax. (Coroutines themselves can be a lot like lightweight threads, depending on just how much stack is preserved…)



  • @dkf I didn't see that aspect of it earlier, but that's actually a good point, especially given the way the progress callout seems to work. It isn't quite a co-routine system as it is, but I can see how you could use it as one... if you wanted to... and had no better way to do it.

    It also has some feel of Python-style generators, in that you could see it as having the progress callout for the 'real' program and the functor that 'is' the promise as a data source or data sink that can be repeatedly calledreturned to as an interrupted closure, but surely there would be better ways to do that even in vanilla Javascript (though that would fit the lazy evaluation model after a fashion). The co-routine use case, as ludicrous as it is, makes more sense than using it for that.

    In any case, my impression is that the main use case it is intended for is, as I said earlier, to create a thunk to a continuation for the purposes of lazy or delayed evaluation, which is sort of the idea implicit in the name 'promise'.

    The real problem I have with it is that it's a camel - not quite lazy evaluation, not quite a generator, not quite a co-routine, and not quite a quaject, any one of which could be implemented with little trouble in Javascript, I think, though generators wouldn't have the language support they have in Python). It is a generalization that doesn't really unify the ideas, and complicates the models rather than simplifying them.


Log in to reply