javascript 中的排序函数调用 - 回调是唯一的方法吗?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12274114/
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
sequencing function calls in javascript - are callbacks the only way?
提问by tim
I read through various threads like this onefor example.
例如,我通读了像这样的各种线程。
But it really escapes me how to accomplish the following:
但它真的让我无法完成以下操作:
I have 4 functions, and want them happen one after another in sequence. Notice they are in incorrect order, to get my point across. I want the result that will output "1, 2, 3, 4'
我有 4 个函数,并希望它们依次发生。注意它们的顺序不正确,以表达我的观点。我想要输出“1、2、3、4”的结果
function firstFunction(){
// some very time consuming asynchronous code...
console.log('1');
}
function thirdFunction(){
// definitely dont wanna do this until secondFunction is finished
console.log('3');
}
function secondFunction(){
// waits for firstFunction to be completed
console.log('2');
}
function fourthFunction(){
// last function, not executed until the other 3 are done.
console.log('4');
}
I tried to figure out callbacks but am getting lost :(
我试图找出回调,但我迷路了:(
Isn't there some simple way to do this? Like looping through an array...
难道没有一些简单的方法可以做到这一点吗?就像遍历数组一样......
回答by zerkms
It's a great chance to start using jQuery Deferred.
这是开始使用jQuery Deferred的好机会。
Apart from the callbacks-based solution the code is readable, flexible and highly maintainable
除了基于回调的解决方案之外,代码可读性强、灵活且可维护性高
http://jsfiddle.net/zerkms/zJhph/
http://jsfiddle.net/zerkms/zJhph/
function firstFunction(){
var d = $.Deferred();
// some very time consuming asynchronous code...
setTimeout(function() {
console.log('1');
d.resolve();
}, 1000);
return d.promise();
}
function thirdFunction(){
var d = $.Deferred();
// definitely dont wanna do this until secondFunction is finished
setTimeout(function() {
console.log('3');
d.resolve();
}, 1000);
return d.promise();
}
function secondFunction(){
var d = $.Deferred();
setTimeout(function() {
console.log('2');
d.resolve();
}, 1000);
return d.promise();
}
function fourthFunction(){
var d = $.Deferred();
// last function, not executed until the other 3 are done.
setTimeout(function() {
console.log('4');
d.resolve();
}, 1000);
return d.promise();
}
firstFunction().pipe(secondFunction).pipe(thirdFunction).pipe(fourthFunction);?
PS: as an example of asynchronous code I've used setTimeout
. The main thing is that in the end of the asynchronous part you need to call d.resolve()
to continue chaining methods.
PS:作为我使用的异步代码示例setTimeout
。主要的是,在异步部分的最后,您需要调用d.resolve()
以继续链接方法。
Further reading: http://joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/
进一步阅读:http: //joseoncode.com/2011/09/26/a-walkthrough-jquery-deferred-and-promise/
回答by jeremy
The idea is you'd do something like the following so that once the first function was done running, it'd know what to run as opposed to you having to figure it out on your own outside the function:
这个想法是你会做类似下面的事情,这样一旦第一个函数运行完毕,它就会知道要运行什么,而不是你必须在函数之外自己弄清楚:
function firstFunction(callback){
// some very time consuming asynchronous code...
console.log('1');
return callback(function(){
alert("Second function finished.");
return true;
});
}
function secondFunction(callback){
// waits for firstFunction to be completed
console.log('2');
return callback();
}
firstFunction(secondFunction);
回答by tim
If I'm using callbacks, my working solution now looks like this:
如果我使用回调,我的工作解决方案现在看起来像这样:
one(two);
function one(callb){
console.log('1');
callb(three);
}
function four(){
console.log('4');
}
function two(callb){
console.log('2');
callb(four);
}
function three(callb){
console.log('3');
callb();
}
I find that hideous. How am I supposed to keep track of this stuff if there is more than 2-3 sequences? Shudder...
我觉得那很可怕。如果有超过 2-3 个序列,我应该如何跟踪这些东西?不寒而栗...
回答by tim
It's been a while and I noticed something about deferreds
in jquery documentation, specifically the when
core API function.
已经有一段时间了,我注意到deferreds
jquery 文档中的一些内容,特别是when
核心 API 函数。
$.when( $.ajax("test.aspx") ).then(function(ajaxArgs){
alert(ajaxArgs[1]); /* ajaxArgs is [ "success", statusText, jqXHR ] */
});
Code sample taken from http://jqapi.com/#p=jQuery.when
回答by SV0505
I have played with the Promise, Sequence, Exception, Callback to understand how it works and finally made this code.
我玩过 Promise、Sequence、Exception、Callback 以了解它是如何工作的,并最终制作了这段代码。
Call functions with callback and send result as parameter to another function in sequence and have a catch errors.
使用回调调用函数并将结果作为参数依次发送给另一个函数并捕获错误。
function firstFunction(par) {
return new Promise(function (resolve, reject) {
console.log("start " + par);
setTimeout(function (par) {
console.log(par);
resolve(par + 1);
}, 1000, par);
});
}
function secondFunction(par) {
return new Promise(function (resolve, reject) {
console.log("start " + par);
setTimeout(function (par) {
console.log(par);
try{
throw "Let's make an error...";
}
catch(err)
{
reject(err);
}
resolve(par + 1);
}, 1000, par);
})
}
function thirdFunction(par) {
return new Promise(function (resolve, reject) {
console.log("start " + par);
setTimeout(function (par) {
console.log(par);
resolve(par + 1);
}, 1000, par);
});
}
function CatchError(error) {
console.log("Exception: " + error);
}
//Break all chain in second function
function ChainBrake() {
firstFunction(1)
.then(secondFunction)
.then(thirdFunction)
.catch(CatchError);
}
//Log error and continue executing chain
function ChainContinue() {
firstFunction(1)
.catch(CatchError)
.then(secondFunction)
.catch(CatchError)
.then(thirdFunction)
.catch(CatchError);
}