Make a jquery function wait till it's previous call has been resolved

后端 未结 4 874
渐次进展
渐次进展 2020-12-21 22:31

So, I\'ve searched for this high and low and maybe I\'m just having trouble understanding jQuery\'s deferred function or I\'m completely on the wrong track. So any help woul

4条回答
  •  死守一世寂寞
    2020-12-21 23:17

    jQuery Deferred Way

    jQuery Deferred object (roughly compromising CommonJS Promises API) can help us managing queued operations. Here is my implementation of queuing messages. You can pass through multiple messages as an array in one call, or synchronize different message boards easily because #messager() returns jQuery object itself but also wrapped as a promise object which will be resolved just when message(s) being displayed.

    (function ($) {
        function awaits($el) {
           var awaits = $el.data('_awaits');
           awaits || $el.data('_awaits', awaits = []);
           return awaits;
        }
      
        function resolveNext(curr /*, ignored */) {
           var head = awaits(this).shift();
           if (head === curr) {
               resolveNext.call(this, 'not await');
           } else {
               head && head.resolve();
           }
        }
      
        function display(message, speed) {
            var $self = this, await = $.Deferred(), willDone = $.Deferred();
            awaits($self).push(await) > 1 || await.resolve();
            
            await.done(function() {
                function reveal() {
                   $self.text(message).fadeIn(speed, function() {
                       resolveNext.call($self, await);
                       willDone.resolve();
                   });
                }
    
                $self.fadeOut(speed/2, reveal);
            });
            return willDone.promise(this);
        };
    
        $.fn.messager = function(message, speed) {
            speed = speed || 500;
    
            if ($.isArray(message)) {
                var arr = [];
                message.forEach(function(m) {
                    arr.push(display.call(this, m, speed));
                }, this);
                return $.when.apply(this, arr);
            } else {
                return display.call(this, message, speed);
            }
        }
    
    }( jQuery ));
    
    
    
    function play() {
      $('#msgbox1').messager(['A demo of', 'queued messages'], 1000);
      for (var i = 3; i > 0; i--) $('#msgbox1').messager(i);
      $('#msgbox1').messager(['Ready to sing...', 'Singing...']);    
      
      for (var i = 8; i > 0; i--) $('#msgbox2').messager('***');    
      for (i = 1; i < 8; i++) $('#msgbox2').messager(String.fromCharCode(64 + i));
      
      $('#msgbox2')
          .messager('')
          .done(function() { 
              $('#msgbox1')
                  .messager(['End of demo.', 'Thank you.', 'Run again?'], 1000)
                  .done(function() {
                      $('#msgbox1, #msgbox2').one('click', play); 
                      $('#msgbox2').messager('>');
                  });
          });
    }
    
    play();
    html {
      background: rgba(0, 0, 0, 0.25);
    }
    #msgbox1, #msgbox2 {
      color: #FFF;
      padding: 0.3em 0.5em;
      font-size: 36pt;
      text-align: center;
      height: 1.8em;
      cursor: default;
    }
    #msgbox2 {
      color: yellow;
    }
    
    
    
      
      Queuing Messages with jQuery Deferred Object
      
    
    
      

提交回复
热议问题