[jquery] 일련의 jQuery 연기로 어떻게 작업합니까?

루트 URL, 스키마 및 특정 순서로 데이터를로드 해야하는 응용 프로그램이 있습니다. 마지막으로 다양한 데이터 객체의 스키마와 URL로 응용 프로그램을 초기화하십시오. 사용자가 애플리케이션을 탐색 할 때 데이터 오브젝트가로드되고 스키마에 대해 유효성이 검증 된 후 표시됩니다. 사용자가 데이터를 CRUD 할 때 스키마는 1 차 유효성 검사를 제공합니다.

초기화에 문제가 있습니다. Ajax 호출을 사용하여 루트 객체 $ .when ()을 가져온 다음 각 스키마 객체마다 하나씩 약속 배열을 만듭니다. 작동합니다. 콘솔에 가져 오기가 표시됩니다.

그런 다음 모든 스키마에 대한 페치가 표시되므로 각 $ .ajax () 호출이 작동합니다. fetchschemas ()는 실제로 약속 배열을 반환합니다.

그러나 마지막 when () 절은 실행되지 않으며 “DONE”이라는 단어가 콘솔에 나타나지 않습니다. jquery-1.5의 소스 코드는 “null”이 $ .when.apply ()에 전달할 객체로 받아 들일 수 있음을 나타냅니다. 통과했다.

이것은 Futures.js를 사용하여 작동했습니다. 이 방법이 아닌 경우 jQuery Deferred 배열을 어떻게 관리해야합니까?

    var fetch_schemas, fetch_root;

    fetch_schemas = function(schema_urls) {
        var fetch_one = function(url) {
            return $.ajax({
                url: url,
                data: {},
                contentType: "application/json; charset=utf-8",
                dataType: "json"
            });
        };

        return $.map(schema_urls, fetch_one);
    };

    fetch_root = function() {
        return $.ajax({
            url: BASE_URL,
            data: {},
            contentType: "application/json; charset=utf-8",
            dataType: "json"
        });
    };

    $.when(fetch_root()).then(function(data) {
        var promises = fetch_schemas(data.schema_urls);
        $.when.apply(null, promises).then(function(schemas) {
            console.log("DONE", this, schemas);
        });
    });



답변

당신이 찾고있는

$.when.apply($, promises).then(function(schemas) {
     console.log("DONE", this, schemas);
}, function(e) {
     console.log("My ajax failed");
});

이것은 또한 작동합니다 (일부 가치의 경우 깨진 아약스를 수정하지 않습니다).

$.when.apply($, promises).done(function() { ... }).fail(function() { ... });` 

inside 가를 참조 하도록 $대신 전달하려고 할 것입니다 . 소스에는 중요하지 않지만 전달하는 것이 좋습니다 .nullthis$.whenjQuerynull

모든 $ .ajax를 교체하고 $.when샘플 작업을 수행 하여 모의

따라서 그것은 아약스 요청의 문제이거나 fetch_schemas에 전달하는 배열입니다.


답변

위의 해결 방법 (감사합니다!) 제대로의 연기에 제공되는 객체 돌아 가지의 문제를 해결하지 않는 resolve()jQuery를가 호출 때문에 방법 done()fail()각각의 매개 변수가 아닌 배열과 콜백을. 즉, arguments의사 배열 을 사용하여 지연된 배열에서 반환 된 모든 확인 / 거부 된 개체를 가져와야합니다.

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

지연된 배열을 전달 했으므로 결과 배열을 다시 가져 오는 것이 좋습니다. 의사 배열 대신 실제 배열을 다시 가져 와서 같은 메소드를 사용할 수도 있습니다 Array.sort().

다음은 이러한 문제를 해결 하는 when.jswhen.all()방법에서 영감을 얻은 솔루션입니다 .

// Put somewhere in your scripting environment
if (jQuery.when.all===undefined) {
    jQuery.when.all = function(deferreds) {
        var deferred = new jQuery.Deferred();
        $.when.apply(jQuery, deferreds).then(
            function() {
                deferred.resolve(Array.prototype.slice.call(arguments));
            },
            function() {
                deferred.fail(Array.prototype.slice.call(arguments));
            });

        return deferred;
    }
}

이제 지연 / 프로 미스 배열을 전달하고 콜백에서 해결 / 거부 된 오브젝트 배열을 다음과 같이 다시 가져올 수 있습니다.

$.when.all(promises).then(function(schemas) {
     console.log("DONE", this, schemas); // 'schemas' is now an array
}, function(e) {
     console.log("My ajax failed");
});


답변

ES6 버전의 자바 스크립트를 사용하는 경우 객체 배열을 쉼표로 구분 된 인수로 변환하는 스프레드 연산자 (…)가 있습니다.

$.when(...promises).then(function() {
 var schemas=arguments;
};

ES6 스프레드 연산자에 대한 자세한 내용 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator here


답변

이 코드로 확장 :

var rawWhen = $.when
$.when = function(promise) {
    if ($.isArray(promise)) {
        var dfd = new jQuery.Deferred()
        rawWhen.apply($, promise).done(function() {
            dfd.resolve(Array.prototype.slice.call(arguments))
        }).fail(function() {
            dfd.reject(Array.prototype.slice.call(arguments))
        })
        return dfd.promise()
    } else {
        return rawWhen.apply($, arguments)
    }
}


답변