javascript 自定义javascript函数中的成功处理
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/11099973/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Success handling in custom javascript function
提问by davids
If I make an ajax call, I can add success handling. I want to add similar logic to my custom functions.
如果我进行 ajax 调用,我可以添加成功处理。我想为我的自定义函数添加类似的逻辑。
I have 6-10 custom functions that MUST be run sequentially or independently. They don't typically run independently so I have them daisy-chained now by calling the next function at the end of the previous but that is messy to read and does not allow for separate execution.
我有 6-10 个必须按顺序或独立运行的自定义函数。它们通常不会独立运行,所以我现在通过在前一个函数的末尾调用下一个函数来将它们菊花链式连接起来,但这很难阅读并且不允许单独执行。
I would love to have something like this:
我很想拥有这样的东西:
function runall(){
runfirst().success(
runsecond().success(
runthird()
))
}
I have had other situations were I would like to add .success()
handling to a custom function, but this situation made it more important.
我还有其他情况,我想.success()
为自定义函数添加处理,但这种情况使它变得更加重要。
If there is another way to force 6-10 functions to run synchronously, that could solve this problem, but I would also like to know how to add success handling to my custom functions.
如果有另一种方法可以强制 6-10 个函数同步运行,那可以解决这个问题,但我也想知道如何为我的自定义函数添加成功处理。
I tried the following based on @lanzz's suggestion:
我根据@lanzz 的建议尝试了以下方法:
I added .then()
to my function(s):
我添加.then()
到我的功能(S):
$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();
}};
The code correctly goes to the end of updateGridRow, gives no errors, but never gets back to call the second function.
代码正确地转到 updateGridRow 的末尾,没有给出任何错误,但永远不会返回调用第二个函数。
I also tried the following as was suggested @Anand:
我还按照@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;
}
};
Which didn't work.
这没有用。
Final Solution
For a great explanation of how to use deferred and make this work see here:
Using Deferred in jQuery
最终解决方案
有关如何使用延迟并使其工作的详细说明,请参见此处:
在 jQuery 中使用延迟
采纳答案by lanzz
How to use Deferreds:
如何使用延迟:
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()');
});
If your functions simply make an AJAX request, you can just return the actual promise returned by $.ajax()
:
如果你的函数只是发出一个 AJAX 请求,你可以只返回由 返回的实际承诺$.ajax()
:
function doAjax() {
return $.ajax({ /* ajax options */ });
}
doAjax().then(function() {
alert('after doAjax()');
});
回答by Anand
If Each of your function returns a state/function and then probably you could add a prototype to each state/function, then you would be able to call the functions like this, in fluent api way(method chaining).
如果您的每个函数都返回一个状态/函数,然后您可能可以为每个状态/函数添加一个原型,那么您将能够以流畅的 api 方式(方法链接)调用这样的函数。
runfirst().runSecond().runThird()
and so on.
等等。
Lemme try to build a sample.
让我试着建立一个样本。
EDIT
编辑
See this, if it fits your design
看看这个,如果它适合你的设计
EDIT 2I did not realise, you were talking about async method chaining. There is very good example here. It was discussed in this stackoverflow thread
回答by CharlesTWall3
From what I can tell you really just want a better way to organize these callbacks. You should use a FIFO array or a queue. Your run all should do your stacking for you then execute the first function.
据我所知,您真的只是想要一种更好的方式来组织这些回调。您应该使用 FIFO 数组或队列。您的 run all 应该为您完成堆叠,然后执行第一个函数。
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();
});
}
}
Usage:
用法:
var queue = [runFirst, runSecond, runThird, ...]
(new RunQueue(queue)).run();
If you really want to get fancy, and you may need to, you could pass in Objects in the array containing your parameters and have RunQueue append the last parameter as the success callback. You could even pass in the context to run the function in that object then call apply or call (whichever one uses the array) on your method.
如果您真的想要花哨并且可能需要,您可以在包含参数的数组中传入 Objects,并让 RunQueue 附加最后一个参数作为成功回调。您甚至可以传入上下文以在该对象中运行该函数,然后在您的方法上调用 apply 或 call(无论哪个使用该数组)。
{
method: runFirst,
context: someObject,
parameters: [param1, param2, param3];
}