KO Delayed Update

by plus5keen

HTML

<table>
    <thead></thead>
    <tbody>
        <tr>
            <th>a</th>
            <td data-bind="text: a"></td>
        </tr>
        <tr>
            <th>b</th>
            <td data-bind="text: b"></td>
        </tr>
        <tr>
            <th>c</th>
            <td data-bind="text: c"></td>
        </tr>
        <tr>
            <th>d</th>
            <td data-bind="text: d"></td>
        </tr>
        <tr>
            <th>d Test</th>
            <td>
                <input data-bind="checked: dTest" type="checkbox" disabled></input>
            </td>
        </tr>
    </tbody>
</table>

JavaScript

// Assume:
// `b` updates at an unknown time after `a` updates.
// `c` updates immediately when `a` updates.
// `d` must not update until `b` has come up-to-date, even though `c` updates.
// We cannot change the implementation of `d`. (Or can we? (What kind of *assumption* ends with "Or can we?"))

// (refer to A,B0,B1,B,C,D graph for initial concept)

var a = ko.observable('a ');

// `b` updates on a delay.
var _b = ko.observable();
var _bUpdate = ko.computed(function () {
    var bValue = a() + 'b ';
    setTimeout(function () {
        _b(bValue);
    }, 3000);
});
var b = ko.computed(function () {
    return _b();
});

var c = ko.computed(function () {
    return a() + 'c ';
});

var d = ko.computed(function () {
    return b() + c() + 'd ';
});

var dTest = ko.computed(function () {
    var dValue = d();
    return dValue[0] === dValue[4];
});

ko.applyBindings({
    a: a,
    b: b,
    c: c,
    d: d,
    dTest: dTest
});

var charCodeSmallA = 'a'.charCodeAt(0);
var getRandomLetter = function () {
    return String.fromCharCode(charCodeSmallA + Math.floor(Math.random() * 26));
};

var updateAToRandomLetter = function () {
    a(getRandomLetter() + ' ');
    setTimeout(function () {
        updateAToRandomLetter();
    }, 6000);
};

updateAToRandomLetter();