3

複数のソースからデータを取得するアプリケーションがあり、すべてのデータが取得された場合にのみ続行します。データをできるだけ速くしたいので、並列リクエストを使用します。

すべてのリクエストがいつ完了したかを把握するために、次のようにしています。

function getData(cb) {

    var count, data;

    count = 0;
    data = {};

    function getDataDone() {
        count++;
        //only call callback when all async requests are done
        if (count === 3 && cb) {
            cb(data);
        }
    }

    foo.doAsync({
        success: function (d) {
            data.foo = d;
            getDataDone();
        }
    });

    bar.doAsync({
        success: function (d) {
            data.bar = d;
            getDataDone();
        }
    });

    $.getJSON("/api/", function (d) {
        data.user = d;
        getDataDone();
    });

} //end getData


getData(function (data) {

    //application data loaded, do stuff
    data.foo;
    data.bar;
    data.user;

});

foo.doAsync、リクエストは並行して発生し、完了すると、カウンターをインクリメントする を呼び出しbar.doAsyncます。カウンターが予想される要求数と等しい場合は、コールバックを実行します。$.getJSONgetDataDone()

この場合、jQuery.deferred はどのように適用されるのでしょうか? そのままコーディングしても問題なく動作します。私が持っているものよりも遅延を使用する利点はありますか?

4

2 に答える 2

1

jQuery.when: http://api.jquery.com/jQuery.when/を使用すると、いくつかの約束が完了するまで待つことができます。

doAsync()メソッドをプロミスでラップできます。

:

function doAsync (opts) {
    var msg = this.msg;
    var data = { json: JSON.stringify({ msg: msg }) };
    $.ajax("/echo/json/", {
        type: "post",
        data: data
    }).then(opts.success);
}

var foo = { msg: "foo", doAsync: doAsync };
var bar = { msg: "bar", doAsync: doAsync };

function createPromise (doAsyncAble) {
    var dfd = $.Deferred();
    doAsyncAble.doAsync({
        success: function (d) {
            dfd.resolve(d);
        }
    });
    return dfd.promise();
}

function getData(cb) {
    var fooPromise = createPromise(foo);
    var barPromise = createPromise(bar);
    var apiPromise = $.ajax("/echo/json/", {
        type: "post",
        data: { json: JSON.stringify({ data: "api" }) }
    });
    $.when(fooPromise, barPromise, apiPromise).done(function (fooResponse, barResponse, apiResponse) {
        var data = {};
        data.foo = fooResponse;
        data.bar = barResponse;
        data.user = apiResponse[0];
        cb(data);
    });

} //end getData


getData(function (data) {
    console.log(data);
});

プロデュース:

ここに画像の説明を入力

コールバックを渡すのではなく、getData から promise を返すこともできます。

于 2013-04-07T11:36:03.397 に答える