Skip to content

Instantly share code, notes, and snippets.

@ismell
Created November 1, 2011 19:45
Show Gist options
  • Save ismell/1331691 to your computer and use it in GitHub Desktop.
Save ismell/1331691 to your computer and use it in GitHub Desktop.
When example
@ismell
Copy link
Author

ismell commented Nov 2, 2011

Awesome! Thanks for the tips. It all makes a lot more sense now. I bit the bullet factored out the legacy on_success and on_error callbacks which also led to cleaner code all around. Does when.js support a .done() method ?
If you look at the callback I have

this.kawrdata_source_name.then(
function(e) {
self.pending_items = false;
deferred.resolve(e);
}, function (e) {
self.pending_items = false;
deferred.reject(e);
}

I set self.pending_items = false; on both the success case and error case. I was wondering if there was a method I could use that would get called on both an error and success.

Thanks,
Raul

@briancavalier
Copy link

Right now, there's no shortcut for a done or finally type handler, but it's something I could consider adding. If you run into more cases where you really need it, let me know.

It's basically equivalent to promise.then(doDoneStuff, doDoneStuff) or when(promise, doDoneStuff, doDoneStuff), so off the top of my head, here's a version of get_data() that does something along those lines, and passes the kawr promise up the stack:

get_data: function(overrides) {
    var self = this;
    var result;

    function reset_pending_items() {
        self.pending_items = false;
    }

    var data_source_name = this.get_data_source_name();

    if (data_source_name && typeof data_source_name === 'string') {
        if (typeof this.kawr[data_source_name] == "function") {
            var params = this.get_data_source_parameters(overrides);

            if (params && typeof params === 'object') {

                this.pending_items = true;

                // this function returns a promise am I chaining it correctly ?
                result = this.kawr[data_source_name](params)
                    .then(reset_pending_items, reset_pending_items);

            } else {

                result = rejected("No parameters we returned");
            }
        } else {
            result = rejected("Method '" + data_source_name + "' not defined on kawr";)
        }
    } else {
        result = rejected("No data source name was defined");
    }

    return result;
}

@ismell
Copy link
Author

ismell commented Nov 2, 2011

Ah that makes things even more clear.
I guess I didn't completely read the comment you added in the last example

// This is subtle: The promise returned here will resolve/reject
// with the return value of on_success/on_error (unless they return undefined),

I was thinking I had to refactor it like so
when(result, reset_pending_items, reset_pending_items)

So I can think of all the .then() chains as mutators unless they return undefined. I guess I can go through and clean up my code a bit more in other places.

Thanks for the help :)

Raul

@briancavalier
Copy link

Thinking of them as mutators is a great way to put it--exactly right. The key is that promise and the promise returned by when or .then are different promises, and thus can have different resolution values.

Whether or not to mutate when undefined is returned is a bit of a gray area, since it's impossible to tell whether the callback intentionally returned undefined, or it simply didn't return a value at all. The Promises/A spec isn't fully clear on it, so I went with not mutating since that seems more intuitive to me ... I mean, how many times have you intentionally written return undefined?!?

BTW, not sure if it was obvious or not, but when(promise, callback, errback) and promise.then(callback, errback) are exactly the same. The advantage of when() is that it can handle situations where you don't know whether you have a promise or a value, e.g.: when(mightBeAPromiseOrARegularValue, callback, errback). It also tends to compress/minify slightly better than .then() :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment