복붙노트

[JQUERY] 아약스 요청을 시퀀싱

JQUERY

아약스 요청을 시퀀싱

해결법


  1. 1.내가 $ .ajaxQueue을 개발 () 플러그인이 사용하는 $ .Deferred, .queue () 및 $ 아약스 ()는 때 요청 완료를 해결 약속을 다시 전달합니다.

    내가 $ .ajaxQueue을 개발 () 플러그인이 사용하는 $ .Deferred, .queue () 및 $ 아약스 ()는 때 요청 완료를 해결 약속을 다시 전달합니다.

    /*
    * jQuery.ajaxQueue - A queue for ajax requests
    * 
    * (c) 2011 Corey Frang
    * Dual licensed under the MIT and GPL licenses.
    *
    * Requires jQuery 1.5+
    */ 
    (function($) {
    
    // jQuery on an empty object, we are going to use this as our Queue
    var ajaxQueue = $({});
    
    $.ajaxQueue = function( ajaxOpts ) {
        var jqXHR,
            dfd = $.Deferred(),
            promise = dfd.promise();
    
        // queue our ajax request
        ajaxQueue.queue( doRequest );
    
        // add the abort method
        promise.abort = function( statusText ) {
    
            // proxy abort to the jqXHR if it is active
            if ( jqXHR ) {
                return jqXHR.abort( statusText );
            }
    
            // if there wasn't already a jqXHR we need to remove from queue
            var queue = ajaxQueue.queue(),
                index = $.inArray( doRequest, queue );
    
            if ( index > -1 ) {
                queue.splice( index, 1 );
            }
    
            // and then reject the deferred
            dfd.rejectWith( ajaxOpts.context || ajaxOpts,
                [ promise, statusText, "" ] );
    
            return promise;
        };
    
        // run the actual query
        function doRequest( next ) {
            jqXHR = $.ajax( ajaxOpts )
                .done( dfd.resolve )
                .fail( dfd.reject )
                .then( next, next );
        }
    
        return promise;
    };
    
    })(jQuery);
    

    당신이 jQuery를 1.4을 사용하는 경우 요소에 대한 아약스 요청에 대한 자신의 "큐"를 만들 빈 개체에 애니메이션 대기열을 활용할 수 있습니다.

    당신은 당신의 자신의 $의 아약스 () 교환이 점을 고려조차 할 수 있습니다. $ .ajaxQueue () 플러그인이 큐가 이미 실행되고 있지 않은 경우 첫 번째 추가 요소를 자동으로 시작합니다 jQuery를위한 표준 'FX'큐를 사용합니다.

    (function($) {
      // jQuery on an empty object, we are going to use this as our Queue
      var ajaxQueue = $({});
    
      $.ajaxQueue = function(ajaxOpts) {
        // hold the original complete function
        var oldComplete = ajaxOpts.complete;
    
        // queue our ajax request
        ajaxQueue.queue(function(next) {
    
          // create a complete callback to fire the next event in the queue
          ajaxOpts.complete = function() {
            // fire the original complete if it was there
            if (oldComplete) oldComplete.apply(this, arguments);
    
            next(); // run the next query in the queue
          };
    
          // run the query
          $.ajax(ajaxOpts);
        });
      };
    
    })(jQuery);
    

    그래서, 우리는 우리가

      에 (Ajax를 사용하여!) 복사 할 몇 가지 <리>가있는

        // get each item we want to copy
        $("#items li").each(function(idx) {
        
            // queue up an ajax request
            $.ajaxQueue({
                url: '/echo/html/',
                data: {html : "["+idx+"] "+$(this).html()},
                type: 'POST',
                success: function(data) {
                    // Write to #output
                    $("#output").append($("<li>", { html: data }));
                }
            });
        });
        

        jsfiddle 데모 - 1.4 버전


      • 2.연기 약속을 사용하여 신속하고 작은 솔루션입니다. 이 jQuery의 $ .Deferred를 사용하지만, 어떤 다른 하나는해야한다.

        연기 약속을 사용하여 신속하고 작은 솔루션입니다. 이 jQuery의 $ .Deferred를 사용하지만, 어떤 다른 하나는해야한다.

        var Queue = function () {
            var previous = new $.Deferred().resolve();
        
            return function (fn, fail) {
                return previous = previous.then(fn, fail || fn);
            };
        };
        

        사용법, 새 대기열을 만들 전화 :

        var queue = Queue();
        
        // Queue empty, will start immediately
        queue(function () {
            return $.get('/first');
        });
        
        // Will begin when the first has finished
        queue(function() {
            return $.get('/second');
        });
        

        비동기 요청을 나란히 비교로 예를 참조하십시오.


      • 3.당신은 간단한 호출과 같은 그 모습을 만들기 위해 함수에 모든 복잡성을 포장 할 수 있습니다 :

        당신은 간단한 호출과 같은 그 모습을 만들기 위해 함수에 모든 복잡성을 포장 할 수 있습니다 :

        loadSequantially(['/a', '/a/b', 'a/b/c'], function() {alert('all loaded')});
        

        다음은 거친 스케치 (AJAX 호출을 제외하고, 예를 들어 작업)입니다. 이것은 배열 대신 대기열 형 구조를 사용하도록 수정 될 수있다

          // load sequentially the given array of URLs and call 'funCallback' when all's done
          function loadSequantially(arrUrls, funCallback) {
             var idx = 0;
        
             // callback function that is called when individual ajax call is done
             // internally calls next ajax URL in the sequence, or if there aren't any left,
             // calls the final user specified callback function
             var individualLoadCallback = function()   {
                if(++idx >= arrUrls.length) {
                   doCallback(arrUrls, funCallback);
                }else {
                   loadInternal();
                }
             };
        
             // makes the ajax call
             var loadInternal = function() {
                if(arrUrls.length > 0)  {
                   ajaxCall(arrUrls[idx], individualLoadCallback);
                }else {
                   doCallback(arrUrls, funCallback);
                }
             };
        
             loadInternal();
          };
        
          // dummy function replace with actual ajax call
          function ajaxCall(url, funCallBack) {
             alert(url)
             funCallBack();
          };
        
          // final callback when everything's loaded
          function doCallback(arrUrls, func)   {
             try   {
                func();
             }catch(err) {
                // handle errors
             }
          };
        

      • 4.이상적으로, 다수의 엔트리 포인트와 코 루틴 서버에서 모든 콜백 같은 코 루틴은 깔끔한 될 것입니다 호출 할 수 있도록. 젠장,이 자바 스크립트 1.7에서 구현하는 것입니다.

        이상적으로, 다수의 엔트리 포인트와 코 루틴 서버에서 모든 콜백 같은 코 루틴은 깔끔한 될 것입니다 호출 할 수 있도록. 젠장,이 자바 스크립트 1.7에서 구현하는 것입니다.

        나 폐쇄를 사용 해보자 ...

        function BlockingAjaxCall (URL,arr,AjaxCall,OriginalCallBack)
        {    
             var nextindex = function()
             {
                 var i =0;
                 return function()
                 {
                     return i++;
                 }
             };
        
             var AjaxCallRecursive = function(){
                     var currentindex = nextindex();
                     AjaxCall
                     (
                         URL,
                         arr[currentindex],
                         function()
                         {
                             OriginalCallBack();
                             if (currentindex < arr.length)
                             {
                                 AjaxCallRecursive();
                             }
                         }
                     );
             };
             AjaxCallRecursive();    
        }
        // suppose you always call Ajax like AjaxCall(URL,element,callback) you will do it this way
        BlockingAjaxCall(URL,myArray,AjaxCall,CallBack);
        

      • 5.다른 답변이 작동하는 동안 그래, 그들은 코드와 지저분한보고 많이 있습니다. Frame.js은 우아하게이 상황을 해결하기 위해 설계되었습니다. https://github.com/bishopZ/Frame.js

        다른 답변이 작동하는 동안 그래, 그들은 코드와 지저분한보고 많이 있습니다. Frame.js은 우아하게이 상황을 해결하기 위해 설계되었습니다. https://github.com/bishopZ/Frame.js

        예를 들어, 이것은 대부분의 브라우저가 중단 될 것입니다 :

        for(var i=0; i<1000; i++){
            $.ajax('myserver.api', { data:i, type:'post' });
        }
        

        동안이되지 않습니다

        for(var i=0; i<1000; i++){
            Frame(function(callback){
                $.ajax('myserver.api', { data:i, type:'post', complete:callback });
            });
        }
        Frame.start();
        

        또한, 프레임을 사용하는 것은 (당신이 원하는 경우)이 완료 AJAX 요청의 전체 시리즈 후 모두와 응답 개체와 거래를 폭포 할 수 있습니다 :

        var listOfAjaxObjects = [ {}, {}, ... ]; // an array of objects for $.ajax
        $.each(listOfAjaxObjects, function(i, item){
            Frame(function(nextFrame){ 
                item.complete = function(response){
                    // do stuff with this response or wait until end
                    nextFrame(response); // ajax response objects will waterfall to the next Frame()
                $.ajax(item);
            });
        });
        Frame(function(callback){ // runs after all the AJAX requests have returned
            var ajaxResponses = [];
            $.each(arguments, function(i, arg){
                if(i!==0){ // the first argument is always the callback function
                    ajaxResponses.push(arg);
                }
            });
            // do stuff with the responses from your AJAX requests
            // if an AJAX request returned an error, the error object will be present in place of the response object
            callback();
        });
        Frame.start()
        

      • 6.나는 그것이 같은 시나리오에서 몇 가지 간단한 솔루션을 찾고, 미래에 다른 사람을 도울 수 있다는 생각이 답변을 게시하고있다.

        나는 그것이 같은 시나리오에서 몇 가지 간단한 솔루션을 찾고, 미래에 다른 사람을 도울 수 있다는 생각이 답변을 게시하고있다.

        이것은 또한 ES6에 소개 된 기본 약속의 지원을 사용 가능하게되었습니다. 당신은 약속 아약스 호출을 감고는 요소의 처리기로 돌아갈 수 있습니다.

        function ajaxPromise(elInfo) {
            return new Promise(function (resolve, reject) {
                //Do anything as desired with the elInfo passed as parameter
        
                $.ajax({
                    type: "POST",
                    url: '/someurl/',
                    data: {data: "somedata" + elInfo},
                    success: function (data) {
                        //Do anything as desired with the data received from the server,
                        //and then resolve the promise
                        resolve();
                    },
                    error: function (err) {
                        reject(err);
                    },
                    async: true
                });
        
            });
        }
        

        이제 당신은 요소의 컬렉션을이 곳에서, 재귀 적으로 함수를 호출합니다.

        function callAjaxSynchronous(elCollection) {
            if (elCollection.length > 0) {
                var el = elCollection.shift();
                ajaxPromise(el)
                .then(function () {
                    callAjaxSynchronous(elCollection);
                })
                .catch(function (err) {
                    //Abort further ajax calls/continue with the rest
                    //callAjaxSynchronous(elCollection);
                });
            }
            else {
                return false;
            }
        }
        

      • 7.그 기능을 얻을 수 http://developer.yahoo.com/yui/3/io/#queue를 사용합니다.

        그 기능을 얻을 수 http://developer.yahoo.com/yui/3/io/#queue를 사용합니다.

        당신이 말한대로 유일한 해결책은 내가 계류중인 호출 / 콜백의 목록을 유지, IS 가지고 올 수 있습니다. 또는 이전 콜백에서 다음 호출을 중첩,하지만 약간의 혼란을 느낀다.


      • 8.그런 다음 사용하여 같은 일을 달성 할 수있다.

        그런 다음 사용하여 같은 일을 달성 할 수있다.

        var files = [
          'example.txt',
          'example2.txt',
          'example.txt',
          'example2.txt',
          'example.txt',
          'example2.txt',
          'example2.txt',
          'example.txt'
        ];
        
        nextFile().done(function(){
          console.log("done",arguments)
        });
        
        function nextFile(text){
          var file = files.shift();
          if(text)
            $('body').append(text + '<br/>');
          if(file)
            return $.get(file).then(nextFile);
        }
        

        http://plnkr.co/edit/meHQHU48zLTZZHMCtIHm?p=preview


      • 9.나는 다른 경우에 재사용 좀 더 정교한 접근 방식을 제안합니다. 나는 사용자가 텍스트 편집기에서 입력이있을 때 호출 순서를 느리게 할 때, 예를 들어 그것을 사용하고 있습니다.

        나는 다른 경우에 재사용 좀 더 정교한 접근 방식을 제안합니다. 나는 사용자가 텍스트 편집기에서 입력이있을 때 호출 순서를 느리게 할 때, 예를 들어 그것을 사용하고 있습니다.

        하지만 그것은 또한 컬렉션을 반복하는 경우에 작동합니다 확신합니다. 이 경우 요청을 대기 할 수 있으며 (12) 대신에 단일 AJAX 호출을 보낼 수 있습니다.

        queueing = {
            callTimeout:                 undefined,
            callTimeoutDelayTime:        1000,
            callTimeoutMaxQueueSize:     12,
            callTimeoutCurrentQueueSize: 0,
        
            queueCall: function (theCall) {
                clearTimeout(this.callTimeout);
        
                if (this.callTimeoutCurrentQueueSize >= this.callTimeoutMaxQueueSize) {
                    theCall();
                    this.callTimeoutCurrentQueueSize = 0;
                } else {
                    var _self = this;
        
                    this.callTimeout = setTimeout(function () {
                        theCall();
                        _self.callTimeoutCurrentQueueSize = 0;
                    }, this.callTimeoutDelayTime);
                }
        
                this.callTimeoutCurrentQueueSize++;
            }
        }
        

      from https://stackoverflow.com/questions/3034874/sequencing-ajax-requests by cc-by-sa and MIT license