Promise object with extra methods

by mistakster

HTML

<div class="progress-bar">
    <div class="progress-gauge">0</div>
</div>
<button class="btn-start">Start calculation</button>
<button class="btn-stop">Stop calculation</button>

CSS

.progress-bar {
    width: 100%;
    height: 20px;
    background: #ddd;
    position: relative;
    overflow: hidden;
}
.progress-gauge {
    width: 0;
    height: 0;
    padding-top: 20px;
    background: #5d7;
    position: absolute;
}
.hidden {
    display: none;
}

JavaScript

function createJob() {
    var dfd = $.Deferred(), value = 0, t, me;
    
    function schedule() {
        return setTimeout(updateValue, 500);
    }
    
    function updateValue() {
        value = value + 10 * Math.random();

        dfd.notifyWith(me, [value > 100 ? 100 : value]);
        
        if (value >= 100) {
            if (value - 100 > 5) {
                dfd.resolveWith(me);
            } else {
                dfd.rejectWith(me);
            }
            t = 0;
        } else {
            t = schedule();
        }
    }

    me = dfd.promise({
        start: function () {
            if (!t) {
                t = schedule();
            }
        },
        stop: function () {
            if (t) {
                clearTimeout(t);
                t = 0;
            }
        }
    });
    
    return me;
}

$(function () {
    
    var job = createJob();
    
    job.done(function () {
        alert("done");
    }).fail(function () {
        alert("fail");
    }).progress(function (value) {
        $(".progress-gauge").width(value + "%");
    }).always(function () {
        $(".btn-start, .btn-stop").addClass("hidden");
    });
        
    $(".btn-start").on("click", function () {
        job.start();
    });
    
    $(".btn-stop").on("click", function () {
        job.stop();
    });
   
});