Yeilding/Chunking Suite

Suite of variants for producing yeilding/chunking in JavaScript

by James Hughes

HTML

<h1>Yield Demo</h1>

<table cellpadding="10" align="center">
    <tr>
        <td>
            <h2>Linear Processing</h2>
            <a href="javascript:;" onclick="doSave('noyield', false); return false;" class="button">Save</a>
            <div id="noyield" class="status_msg">Ready</div>
        </td>
        <td>
            <h2>Yielding</h2>
            <a href="javascript:;" onmousedown="doSave('yield', true); return false;" class="button">Save</a>
            <div id="yield" class="status_msg">Ready</div>
        </td>
        <td>
            <h2>Asynchronous Update Seldom</h2>            
            <a href="javascript:;" onmousedown="doSave('chunk1', 'chunk', 'seldom'); return false;" class="button">Save</a>
            <div id="chunk1" class="status_msg">Ready</div>
        </td>
        <td>
            <h2>Asynchronous Update Often</h2>
            <a href="javascript:;" onmousedown="doSave('chunk2', 'chunk', 'often'); return false;" class="button">Save</a>
            <div id="chunk2" class="status_msg">Ready</div>
        </td>
        <td>
            <h2>Asynchronous Update Very Often</h2>
            <a href="javascript:;" onmousedown="doSave('chunk3', 'chunk', 'very-often'); return false;" class="button">Save</a>
            <div id="chunk3" class="status_msg">Ready</div>
        </td>
    </tr>
    <tr>
        <td colspan="6">
            Input for Response Test: <input type="text"/>
            <td>
            </tr>
            </table>

CSS

.button {
    border: 1px solid black;
    background: #fff;
    padding: 5px;
    color: black;
    text-decoration: none;
}

.button:hover{
    background: #ddd;
}
.status_msg {
    color: #999;
    margin-top: 0.5em;
    font-size: 18pt;
}

td {
    text-align:center;
}

h2{
    margin-bottom:10px;
}

JavaScript

(function() {
    // increase this to lengthen processing time
    var numIters = 999999999;

    function doSave(id, doYield, updateFrequency) {
        document.getElementById(id).innerHTML = '<span style="font-style: italic;">Saving...</span>';
        if (doYield === true) {
            setTimeout(function() {
                doSaveImpl(id);
            }, 0);
        } else if (doYield === 'chunk') {
            switch (updateFrequency) {
            case "very-often":
                doSaveChunkImpl(id, Math.round(numIters / 1000));
                break;
            case "seldom":
                doSaveChunkImpl(id, Math.round(numIters / 10));
                break;
            case "often":
            default:
                doSaveChunkImpl(id, Math.round(numIters / 100));
                break;
            }
            //doSaveChunkImpl(id)
        } else {
            doSaveImpl(id);
        }
    }




    function doSaveImpl(id) {
        var numIters = 9999999;
        for (var i = 0; i < numIters; i++) {
            var j = Math.sqrt(i); // slow operation
        }

        document.getElementById(id).innerHTML = '<span style="color: #090">Saved!</span>';
    }

    function doSaveChunkImpl(id, chunkSize) {


        var i = 0;
        (function() {
            var count = 0;
            for (; i < numIters; i++) {
                var j = Math.sqrt(i);
                count++;
                if (count == chunkSize) break;
            }
            if (i < numIters) {
                document.getElementById(id).innerHTML = '<span style="color: #090">' + Math.round((i / numIters) * 100) + '% Complete</span>';
                setTimeout(arguments.callee, 0);
            } else {
                document.getElementById(id).innerHTML = '<span style="color: #090">Saved!</span>';
            }
        })();
    }

    window.doSave = doSave;
}());