6

ajax呼び出しを行うと、成功処理を追加できます。カスタム関数に同様のロジックを追加したいと思います。

順次または独立して実行する必要がある6〜10個のカスタム関数があります。通常、これらは独立して実行されないため、前の関数の最後に次の関数を呼び出すことでデイジーチェーン接続しますが、読み取りが面倒で、個別に実行することはできません。

私はこのようなものが欲しいです:

function runall(){
    runfirst().success(
        runsecond().success(
            runthird()
    ))
} 

カスタム関数に処理を追加したいという他の状況もありました.success()が、この状況はそれをより重要にしました。

6〜10個の関数を強制的に同期的に実行する別の方法がある場合は、この問題を解決できますが、カスタム関数に成功処理を追加する方法も知りたいです。

@lanzzの提案に基づいて次のことを試しました。

関数に追加.then()しました:

$bomImport.updateGridRow(rowId).then(function () {
        $bomImport.toggleSubGrid(rowId, false);
});


var $bomImport = {
  updateGridRow: function (rowId) {
    $('#' + rowId + ' td[aria-describedby="bomImport_rev"]').html($("#mxRevTxt").val());
    $('#' + rowId + ' td[aria-describedby="bomImport_itemno"]').html($("#itemNoTxt").val());
    $('#' + rowId + ' td[aria-describedby="bomImport_used"]').html($("#usedTxt").val());
    $('#' + rowId + ' td[aria-describedby="bomImport_partSource"]').html($("#partSourceTxt").val());
    $('#' + rowId + ' td[aria-describedby="bomImport_partClass"]').html($("#partClassTxt").val());
    $('#' + rowId + ' td[aria-describedby="bomImport_partType"]').html($("#partTypeTxt").val());
    $('#' + rowId + ' td[aria-describedby="bomImport_partno"]').html($("#mxPnTxt").val());
    $('#' + rowId + ' td[aria-describedby="bomImport_descript"]').html($("#descTxt").val());
    $('#' + rowId + ' td[aria-describedby="bomImport_qty"]').html($("#qtyTxt").val());
    $('#' + rowId + ' td[aria-describedby="bomImport_custPartNo"]').html($("#custPartNoTxt").val());
    $('#' + rowId + ' td[aria-describedby="bomImport_crev"]').html($("#custRevTxt").val());
    $('#' + rowId + ' td[aria-describedby="bomImport_u_of_m"]').html($("#uomTxt").val());
    $('#' + rowId + ' td[aria-describedby="bomImport_warehouse"]').html($("#warehouseTxt").val());
    $('#' + rowId + ' td[aria-describedby="bomImport_standardCost"]').html($("#stdCostTxt").val());
    $('#' + rowId + ' td[aria-describedby="bomImport_workCenter"]').html($("#wcTxt").val());
    var defferred = new $.Deferred();
    return defferred.promise();
}};

コードは正しくupdateGridRowの最後に移動し、エラーは発生しませんが、2番目の関数を呼び出すために戻ることはありません。

@Anandが提案したように、私も次のことを試しました。

workSheetSaveExit(rowId, isNew).save().updateRow().toggle();
function workSheetSaveExit(){
    this.queue = new Queue;
    var self = this;
    self.queue.flush(this);
}
workSheetSaveExit.prototype = {
  save: function () {
    this.queue.add(function (self) {
        $bomImport.workSheetSave(rowId, isNew);
    });
    return this;
  },
  updateRow: function () {
    this.queue.add(function (self) {
        $bomImport.updateGridRow(rowId);
    });
    return this;
  },
  toggle: function () {
    this.queue.add(function (self) {
        $bomImport.toggleSubGrid(rowId, false);
    });
    return this;
  }
};

これはうまくいきませんでした。

最終的な解決策deferredを使用してこの動作を実現する方法の詳細については、jQueryでのDeferredの使用を
参照してください。

4

3 に答える 3

5

延期の使用方法:

function somethingAsynchronous() {
    var deferred = new $.Deferred();
    // now, delay the resolution of the deferred:
    setTimeout(function() {
        deferred.resolve('foobar');
    }, 2000);
    return deferred.promise();
}

somethingAsynchronous().then(function(result) {
    // result is "foobar", as provided by deferred.resolve() in somethingAsynchronous()
    alert('after somethingAsynchronous(): ' + result);
});

// or, you can also use $.when() to wait on multiple deferreds:
$.when(somethingAsynchronous(), $.ajax({ something })).then(function() {
    alert('after BOTH somethingAsynchronous() and $.ajax()');
});

関数が単にAJAXリクエストを行う場合は、$.ajax():によって返される実際のpromiseを返すことができます。

function doAjax() {
    return $.ajax({ /* ajax options */ });
}

doAjax().then(function() {
    alert('after doAjax()');
});
于 2012-06-19T15:58:10.480 に答える
0

私が言えることから、これらのコールバックを整理するためのより良い方法が本当に必要です。FIFOアレイまたはキューを使用する必要があります。すべての実行でスタッキングを実行してから、最初の関数を実行する必要があります。

var RunQueue = function(queue){
    this.init(queue);
}

var p = RunQueue.prototype = {};

p.queue = null;

p.init = function(queue){
    this.queue = queue.slice(); //copy the array we will be changing it
                                // if this is not practical, keep an index
}

p.run = function(){
    if(this.queue && this.queue.length) {
        var first = this.queue[0];
        this.queue.shift();
        var runQueue = this;
        first(function(){ /*success callback parameter*/
            runQueue.run();
        });
    }
}

使用法:

var queue = [runFirst, runSecond, runThird, ...]

(new RunQueue(queue)).run();

本当に凝ったものにしたい場合、そして必要になるかもしれない場合は、パラメーターを含む配列内のオブジェクトを渡し、RunQueueに最後のパラメーターを成功コールバックとして追加させることができます。コンテキストを渡してそのオブジェクトで関数を実行し、メソッドでapplyまたはcall(配列を使用する方)を呼び出すこともできます。

{
    method: runFirst,
    context: someObject,
    parameters: [param1, param2, param3];
}
于 2012-06-19T12:27:48.737 に答える
0

各関数が状態/関数を返し、おそらく各状態/関数にプロトタイプを追加できる場合は、流暢なAPI方式(メソッドチェーン)でこのような関数を呼び出すことができます。

runfirst().runSecond().runThird() 

等々。

Lemmeはサンプルを作成しようとします。

編集

あなたのデザインに合うなら、これを見てください

編集2 私は気づいていませんでした、あなたは非同期メソッドチェーンについて話していました。ここに非常に良い例があります。それはこのstackoverflowスレッドで議論されました

于 2012-06-19T11:35:34.817 に答える