自定义 JavaScript 函数中的成功处理

Success handling in custom javascript function

本文关键字:成功 处理 JavaScript 函数 自定义      更新时间:2023-09-26

如果我进行 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 的末尾,没有给出任何错误,但永远不会返回调用第二个函数。

我还按照@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;
  }
};

这行不通。

最终解决方案
有关如何使用延迟并使这项工作的精彩解释,请参见此处:在 jQuery 中使用延迟

如何使用延迟:

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() 返回的实际承诺:

function doAjax() {
    return $.ajax({ /* ajax options */ });
}
doAjax().then(function() {
    alert('after doAjax()');
});

据我所知,您真的只是想要一种更好的方法来组织这些回调。您应该使用 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();

如果你真的想变得花哨,并且可能需要这样做,你可以在包含参数的数组中传入 Objects,并让 RunQueue 附加最后一个参数作为成功回调。您甚至可以传入上下文以在该对象中运行函数,然后在您的方法上调用 apply 或调用(无论使用数组的哪个)。

{
    method: runFirst,
    context: someObject,
    parameters: [param1, param2, param3];
}

如果你的每个函数都返回一个状态/函数,然后你可能为每个状态/函数添加一个原型,那么你就可以像这样调用函数,以流畅的 api 方式(方法链)。

runfirst().runSecond().runThird() 

等等。

莱姆尝试构建一个示例。

编辑

看看这个,如果它适合你的设计

编辑 2我没有意识到,您正在谈论异步方法链接。这里有一个很好的例子。在此堆栈溢出线程中进行了讨论