Skip to content

Use an observable as a jQuery promise

Sylvain Garden edited this page Jan 23, 2018 · 5 revisions

Information on jQuery promise: http://api.jquery.com/category/deferred-object/

edit: ko.when now defined as a simple callback API: https://github.com/miellaby/knockout/blob/master/src/subscribables/observableUtils.js

ko.$when = function(observable) {
    var deferred = $.Deferred(), value = observable.peek(), subs;
    if (value) {
        deferred.resolve(value);
    } else {
        subs = observable.subscribe(function(newValue) {
            if (newValue) {
                subs.dispose();
                deferred.resolve(newValue);
            }
        });
    }
    return deferred;
};

Variant based upon on-the-fly computed

ko.$when(predicate) promise is resolved once predicate() gets true

    /**
     * make JQuery promise out of a observable-based condition
     * @param {function} predicate
     * @returns {JQuery.Promise}
     */
    ko.$when = function(predicate) {
        return $.Deferred(function(deferred) {
            var observable = ko.pureComputed(predicate).extend({ notify:'always' });
            var subscription = observable.subscribe(onChange);
            function onChange(value) {
                if (value) {
                    subscription.dispose();
                    observable.dispose();
                    deferred.resolve(value);
                }
            }
            // In case the initial value is true, process it right away
            onChange(observable.peek());
        }).promise();
    };