2

JSFiddle コード

パイプとチェーンは私にとって新しいものです...

この小さなスクリプトを機能させるのに問題があります。AJAX で同期的にトリガーする必要がある URL の配列があります。次の繰り返しにパイプする前に、各 URL からの成功の応答を待つ必要があります (大きな SQL クエリを実行してレポートを作成するため、遅延がある場合があります)。成功しない場合は、プロセス全体を停止する必要があります。

私は多くのことをいじった後、私は近くにいると思いますが、正しく機能していないことがわかります。おそらく、あなたの教祖の一人がこれについて私を助けることができますか?

    //counter
var i = 0;

//array of local urls that I need to trigger one after another
var arrValues = [
    "http://fiddle.jshell.net/",
    "http://fiddle.jshell.net/",
    "http://fiddle.jshell.net/"];

//the step i need to repeat until done
var step = (function () {

    //expect to see this alert called for each iteration (only happens once?)
    alert(arrValues[i]+i);

    var url = arrValues[i];
    var model = {};

    model.process = function () {
        log('Starting: ' + url + i);

        return $.ajax(url)
            .done(function (jqXHR, textStatus, errorThrown) {
            log(textStatus + ' ' + url + i + ' Done');
        })
            .fail(function (jqXHR, textStatus, errorThrown) {
            log(textStatus + ' Failed');
        });
    };

    return model;
}());

//just outputting to the div here
function log(message) {
    $("#output").append($("<div></div>").text(message));
}

//start the process
log("Starting To Build Report");

//iterate through the array
$.each(arrValues, function (intIndex, objValue) {

    // I need to wait for success before starting the next step or fail and throw
    // the errors below - you will see this does not work now and never gets to the 
    // .done or .fail or .always

    step.process().pipe( function () {
        i++;
        step.process();
    });

}).done(function () {
    log("The process completed successfully");
})
    .fail(function () {
    log("One of the steps failed");
})
    .always(function () {
    log("End of process");
});
4

1 に答える 1

1

もうすぐですが、詳細は非常に重要です。コツは:

  • 関数を返す関数 (オブジェクトではない)に変更stepし、それ自体が監視可能なオブジェクト (つまり、jqXHR promise) を返す関数を返します。
  • step増分整数iをパラメータとして受け入れることを許可します。iこれにより、外側のスコープで実行を維持する必要がなくなります
  • によって返された関数を引数として取る.then()チェーンを構築するthen()step()
  • .then()解決済みの Promise をチェーンにシードして開始する
  • .done()最後の, .fail(),をチェーン.always()の最後に付けます。then()

注: jQuery 1.8 から、.pipe()は廃止され、改訂され.then()た .

コードは次のとおりです。

var arrValues = [
    "http://fiddle.jshell.net/",
    "http://fiddle.jshell.net/",
    "http://fiddle.jshell.net/"
];

function step(i) {
    return function() {
        var url = arrValues[i];
        log('Starting: ' + url + i);
        return $.ajax(url).done(function(data, textStatus, jqXHR) {
            log(textStatus + ' ' + url + i + ' Done');
        }).fail(function(jqXHR, textStatus, errorThrown) {
            log(textStatus + ' ' + url + i + ' Failed');
        });
    }
};

function log(message) {
    $("#output").append($("<div/>").text(message));
}

log("Starting To Build Report");

var p = $.Deferred().resolve().promise();
$.each(arrValues, function(i, url) {
    p = p.then(step(i));
});
p.done(function() {
    log("The process completed successfully");
}).fail(function() {
    log("One of the steps failed");
}).always(function() {
    log("End of process");
});

更新されたフィドル

于 2013-03-15T21:22:45.987 に答える