source

지연 배열을 $.when()에 전달합니다.

manycodes 2023. 1. 9. 21:15
반응형

지연 배열을 $.when()에 전달합니다.

다음은 무슨 일이 일어나고 있는지 보여주는 http://jsfiddle.net/adamjford/YNGcm/20/의 예시입니다.

HTML:

<a href="#">Click me!</a>
<div></div>

JavaScript:

function getSomeDeferredStuff() {
    var deferreds = [];

    var i = 1;
    for (i = 1; i <= 10; i++) {
        var count = i;

        deferreds.push(
        $.post('/echo/html/', {
            html: "<p>Task #" + count + " complete.",
            delay: count
        }).success(function(data) {
            $("div").append(data);
        }));
    }

    return deferreds;
}

$(function() {
    $("a").click(function() {
        var deferreds = getSomeDeferredStuff();

        $.when(deferreds).done(function() {
            $("div").append("<p>All done!</p>");
        });
    });
});

" Done을 "All Done!"은 "All Done!"입니다.'그냥'$.when()지연 에 " done된 것으로 간주합니다.'모두 끝!'"이 먼저 발생하므로 jQuery는 방금 완료되었다고 가정합니다.

어떤 사람은 그 물건들을 함수에 넘겨줄 수 있다는 걸 알아요$.when(deferred1, deferred2, ..., deferredX)그러나 실제로 해결하려는 문제에 실행 중인 지연 객체가 몇 개 있는지 알 수 없습니다.

값의 배열을 일반적으로 별도의 매개 변수가 될 것으로 예상되는 함수에 전달하려면Function.prototype.apply 이 아까다'가 필요해요

$.when.apply($, my_array).then( ___ );

http://jsfiddle.net/YNGcm/21/ 를 참조해 주세요.

ES6를 사용할 수 .... 대신 산포 연산자:

$.when(...my_array).then( ___ );

알 수 있는 에 공식 를 알 수 .then「처리」, 「처리」, 「처리」가하게 됩니다.arguments각 약속의 결과를 가져오기 위해 배열합니다.

고맙습니다!)에서는 「고맙습니다」에 않습니다.에서는 지연된 사용자에게 제공된 개체를 반환하는 문제를 제대로 해결하지 못했습니다.resolve()가 메서드 jQuery를 하기 입니다.done() ★★★★★★★★★★★★★★★★★」fail()배열이 아닌 개별 파라미터를 사용한 콜백., '', '아까', '아까', '아까'를 .arguments에 의해된 개체 를 모두 개체는추악한 배열입니다.이것은 추한 것입니다.

$.when.apply($,deferreds).then(function() {
     var objects = arguments; // The array of resolved objects as a pseudo-array
     ...
};

지연된 결과 배열을 전달했으므로 결과 배열을 돌려받는 것이 좋을 것 같습니다..Array.sort().

다음은 언제.js의 소프트웨어에서 영감을 얻은 솔루션입니다.when.all()다음과 같이 합니다.

// Put somewhere in your scripting environment
if (typeof jQuery.when.all === 'undefined') {
    jQuery.when.all = function (deferreds) {
        return $.Deferred(function (def) {
            $.when.apply(jQuery, deferreds).then(
            // the calling function will receive an array of length N, where N is the number of
            // deferred objects passed to when.all that succeeded. each element in that array will
            // itself be an array of 3 objects, corresponding to the arguments passed to jqXHR.done:
            // ( data, textStatus, jqXHR )
            function () {
                var arrayThis, arrayArguments;

                if (Array.isArray(this)) {
                    arrayThis = this;
                    arrayArguments = arguments;
                }
                else {
                    arrayThis = [this];
                    arrayArguments = [arguments];
                }

                def.resolveWith(arrayThis, [Array.prototype.slice.call(arrayArguments)]);
            },
            // the calling function will receive an array of length N, where N is the number of
            // deferred objects passed to when.all that failed. each element in that array will
            // itself be an array of 3 objects, corresponding to the arguments passed to jqXHR.fail:
            // ( jqXHR, textStatus, errorThrown )
            function () {
                var arrayThis, arrayArguments;

                if (Array.isArray(this)) {
                    arrayThis = this;
                    arrayArguments = arguments;
                }
                else {
                    arrayThis = [this];
                    arrayArguments = [arguments];
                }

                def.rejectWith(arrayThis, [Array.prototype.slice.call(arrayArguments)]);
            });
        });
    }
}

다음과 같이 연기/약속 배열을 전달하고 해결/거부된 객체 배열을 콜백으로 되돌릴 수 있습니다.

$.when.all(deferreds).then(function(objects) {
    console.log("Resolved objects:", objects);
});

'적용하다를 적용할 수 요.when이치노

var arr = [ /* Deferred objects */ ];

$.when.apply($, arr);

jQuery Delferreds 배열에서는 어떻게 작업합니까?

복수의 병행 AJAX 콜을 호출하는 경우, 각각의 응답을 처리하기 위한 2개의 옵션이 있습니다.

  1. 동기식 AJAX 호출 사용/ 연속 사용/ 권장 안 함
  2. 사용하다Promises'array 및 array를 받아들인다.promise및 그 콜백.done이 모든 일이 일어날 때promise는 각각의 응답과 함께 정상적으로 반환됩니다.

function ajaxRequest(capitalCity) {
   return $.ajax({
        url: 'https://restcountries.eu/rest/v1/capital/'+capitalCity,
        success: function(response) {
        },
        error: function(response) {
          console.log("Error")
        }
    });
}
$(function(){
   var capitalCities = ['Delhi', 'Beijing', 'Washington', 'Tokyo', 'London'];
   $('#capitals').text(capitalCities);

   function getCountryCapitals(){ //do multiple parallel ajax requests
      var promises = [];   
      for(var i=0,l=capitalCities.length; i<l; i++){
            var promise = ajaxRequest(capitalCities[i]);
            promises.push(promise);
      }
  
      $.when.apply($, promises)
        .done(fillCountryCapitals);
   }
  
   function fillCountryCapitals(){
        var countries = [];
        var responses = arguments;
        for(i in responses){
            console.dir(responses[i]);
            countries.push(responses[i][0][0].nativeName)
        }  
        $('#countries').text(countries);
   }
  
   getCountryCapitals()
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div>
  <h4>Capital Cities : </h4> <span id="capitals"></span>
  <h4>Respective Country's Native Names : </h4> <span id="countries"></span>
</div>

간단한 대안으로, 그것은 다음을 필요로 하지 않는다.$.when.apply또는array다음 패턴을 사용하여 여러 병렬 약속에 대한 단일 약속을 생성할 수 있습니다.

promise = $.when(promise, anotherPromise);

예.

function GetSomeDeferredStuff() {
    // Start with an empty resolved promise (or undefined does the same!)
    var promise;
    var i = 1;
    for (i = 1; i <= 5; i++) {
        var count = i;

        promise = $.when(promise,
        $.ajax({
            type: "POST",
            url: '/echo/html/',
            data: {
                html: "<p>Task #" + count + " complete.",
                delay: count / 2
            },
            success: function (data) {
                $("div").append(data);
            }
        }));
    }
    return promise;
}

$(function () {
    $("a").click(function () {
        var promise = GetSomeDeferredStuff();
        promise.then(function () {
            $("div").append("<p>All done!</p>");
        });
    });
});

주의:

  • 누군가 연쇄적으로 약속을 하는 걸 보고 알아냈어요promise = promise.then(newpromise)
  • 단점은 백그라운드에서 추가 약속 개체가 생성되고 마지막에 전달되는 파라미터는 (추가 개체 내에 중첩되므로) 그다지 유용하지 않다는 것입니다.짧고 간단하지만 당신이 원하는 것을 위해.
  • 장점은 어레이나 어레이 관리가 필요하지 않다는 것입니다.

각각 $.를 사용하는 다른 것을 제안하고 싶습니다.

  1. 다음과 같이 ajax 함수를 선언할 수 있습니다.

    function ajaxFn(someData) {
        this.someData = someData;
        var that = this;
        return function () {
            var promise = $.Deferred();
            $.ajax({
                method: "POST",
                url: "url",
                data: that.someData,
                success: function(data) {
                    promise.resolve(data);
                },
                error: function(data) {
                    promise.reject(data);
                }
            })
            return promise;
        }
    }
    
  2. 전송할 Ajax를 사용하여 함수 배열을 만드는 코드:

    var arrayOfFn = [];
    for (var i = 0; i < someDataArray.length; i++) {
        var ajaxFnForArray = new ajaxFn(someDataArray[i]);
        arrayOfFn.push(ajaxFnForArray);
    }
    
  3. 또한 Ajax를 전송하는 호출 함수:

    $.when(
        $.each(arrayOfFn, function(index, value) {
            value.call()
        })
    ).then(function() {
            alert("Cheer!");
        }
    )
    

변환 중이고 ES6에 액세스할 수 있는 경우 분산 구문을 사용하여 개체 각각의 반복 가능한 항목을 개별 인수로 적용할 수 있습니다.$.when()요합니니다다

$.when(...deferreds).done(() => {
    // do stuff
});

MDN 링크 - 확산 구문

각 루프에 투고하고 나서, Ajax 로부터 수신한 번호로부터 몇개의 필드에 html 마크업을 설정하는, 매우 유사한 케이스가 있었습니다.그런 다음 이러한 필드의 (지금 갱신된) 값을 합산하여 총 필드에 배치해야 했습니다.

그 때문에, 문제는, 모든 번호에 대해서 합계를 시도하고 있었지만, 비동기 Ajax 콜로부터 아직 데이터가 도착하지 않은 것입니다.코드를 재사용하기 위해서는 몇 가지 기능으로 이 기능을 완료해야 했습니다.외부 기능은 데이터를 기다린 후 완전히 업데이트된 DOM을 사용하여 작업을 수행합니다.

    // 1st
    function Outer() {
        var deferreds = GetAllData();

        $.when.apply($, deferreds).done(function () {
            // now you can do whatever you want with the updated page
        });
    }

    // 2nd
    function GetAllData() {
        var deferreds = [];
        $('.calculatedField').each(function (data) {
            deferreds.push(GetIndividualData($(this)));
        });
        return deferreds;
    }

    // 3rd
    function GetIndividualData(item) {
        var def = new $.Deferred();
        $.post('@Url.Action("GetData")', function (data) {
            item.html(data.valueFromAjax);
            def.resolve(data);
        });
        return def;
    }

JS나 Q 을 사용하고 JS 약속 Q가 있습니다..all()이 문제를 해결하는 방법.

var savePromises = [];
angular.forEach(models, function(model){
  savePromises.push(
    model.saveToServer()
  )
});

$q.all(savePromises).then(
  function success(results){...},
  function failed(results){...}
);

자세한 내용은 다음 API를 참조하십시오.

https://github.com/kriskowal/q/wiki/API-Reference#promiseall

https://docs.angularjs.org/api/ng/service/$q

언급URL : https://stackoverflow.com/questions/5627284/pass-in-an-array-of-deferreds-to-when

반응형