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(function() {
            var self = this;

            var callback = function() {
                self.args = [].slice.call(arguments);
                self.args.unshift(callback);
                if (self.deferred.length) {
                    self.done = false;
                    self.deferred[0].apply(self, self.args);
                    self.deferred.shift();
                }
                if (!self.deferred.length) {
                    self.done = true;
                }

            }



            this.wait = function(run) {

                if (self.done) {
                    console.log(self.args)
                    run.apply(self, self.args);
                    self.done = false;
                } else {
                    this.deferred.push(run);
                }
                return self;
            }

            this.deferred = [];

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

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

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

    }).wait(function(runNext, a, b) {
        log('Вторая анимация пошла, a=' + a + ' b=' + b); //используем аргументы из предыдущего вызова
        this.states.c = 7;
        this.states.d = 8;

        $('#div2').animate({
            top: 50
        }, 1000, runNext);

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

        setTimeout(function() {
            log('Две секунды прошли');
            log('Выполнена последняя функция из цепочки');
            runNext(1, 3);
        }, 1000);

    })

    setTimeout(function() {
        log('Большая задержка...