JSFiddle - React, Tailwind, and code Playground

by finom

HTML

<div id="div1"></div>
<div id="div2"></div>
<div id="div3"></div>
<div id="info"></div>

CSS

div {
    width: 40px;
    height: 40px; 
    position: absolute;
}

#div1 {
    background-color: red;
}
#div2 {
    background-color: green;
    left: 45px;
}
#div3 {
    background-color: blue;
    left: 90px;
}

#info {
    position: absolute;
    bottom: 0;
    width: 100%;
    height: 50%;
}

JavaScript

(function() {
    wait = function(first) {
        return new wait.Init(first);
    }

    wait.Init = function(first) {
        var self = this;
        this.callbackCaller = function() {
            self.callback.apply(self, arguments);
        }

        first.call(this, this.callbackCaller);
    }

    wait.Init.prototype = {
        deferred: [],
        callback: function() {
            this.args = [].slice.call(arguments);
            this.args.unshift(this.callbackCaller);
            if (this.deferred.length) {
                this.done = false;
                this.deferred[0].apply(this, this.args);
                this.deferred.shift();
            }
            if (!this.deferred.length) {
                this.done = true;
            }

        },

        wait: function(run) {

            if (this.done) {
                this.done = false;
                run.apply(this, this.args);

            } else {
                this.deferred.push(run);
            }
            return this;
        },
        data: function(item, value) {

            if (arguments.length === 2) {
                this.data[item] = value;
            } else {
                return this.data[item];
            }
        }
    }




    var log = function(text) {
        $('#info').prepend(text + '<br>');
    }

    /* Пример */
    w = wait(function(runNext) {
        log('Первая анимация пошла');
        this.data('var1', 1);
        this.data.var2 = 2;
        $('#div1').animate({
            top: 30
        }, 1000, function() {
            runNext(1, 2); //передаем какие-нибудь аргументы в следующий вызов
        });
    }).wait(function(runNext, a, b) {

        log('Вторая анимация пошла, a=' + a + ' b=' + b); //используем аргументы из предыдущего вызова
        $('#div2').animate({
            top: 50
        }, 1000, runNext);

    }).wait(function(runNext) {
        log('Ждем две секунды');

        setTimeout(function() {
            log('Две секунды прошли');
 ...