在上一个函数完成后调用一个函数

IT技术 javascript jquery
2021-01-15 18:31:03

我有以下 JavaScript 代码:

$('a.button').click(function(){
    if (condition == 'true'){
        function1(someVariable);
        function2(someOtherVariable);
    }
    else {
        doThis(someVariable);
    }
});

如何确保function2仅在function1完成后才调用

6个回答

指定一个匿名回调,并让 function1 接受它:

$('a.button').click(function(){
    if (condition == 'true'){
        function1(someVariable, function() {
          function2(someOtherVariable);
        });
    }
    else {
        doThis(someVariable);
    }
});


function function1(param, callback) {
  ...do stuff
  callback();
} 
+1 但如果他使用 1.5,他就可以使用新的 Deferreds 模式
2021-03-19 18:31:03
感谢您的快速回复)。是的,function1 只是执行一个简单的异步任务,所以我相信你是正确的,因为我必须创建一个回调——或者看看 philwinkle 提到的这个延迟业务。再次感谢各位。我要睡一会,明天早上再解决这个问题。
2021-04-03 18:31:03
@MikeRobinson 问题是:如果...do stuff包含异步内容怎么办?Function2 仍不会按预期触发。我上面评论中的示例表明,因为该foo()函数中有异步代码,所以bar()foo()的内容执行完成后不会触发它的内容,即使使用$.when().then()一个接一个地调用它们。只有(且仅当)...do stuff您的代码中的所有内容都严格同步此答案才有效
2021-04-03 18:31:03
@trusktr 在这种情况下,您需要将第一个回调继续传递到第n个异步调用级别,然后callBack()在所有n 个异步调用完成触发由于 OP 没有提到他在函数中所做的事情,因此将其假定为一级异步调用。
2021-04-10 18:31:03
这个答案不是解决方案。这是它不起作用的证据:jsfiddle.net/trusktr/M2h6e
2021-04-11 18:31:03

如果您使用的是 jQuery 1.5,则可以使用新的 Deferreds 模式:

$('a.button').click(function(){
    if(condition == 'true'){
        $.when(function1()).then(function2());
    }
    else {
        doThis(someVariable);
    }
});

编辑:更新博客链接:

丽贝卡墨菲在这里写了一篇很棒的文章:http : //rmurphey.com/blog/2010/12/25/deferreds-coming-to-jquery/

Rebecca Murphy 的文章是在 Defferds 被引入 jQuery 之前写的,它使用了基于作者认为它将如何实现的示例。请访问 jQuery 的站点以了解如何实际使用此功能:api.jquery.com/jQuery.Deferred
2021-03-13 18:31:03
即使使用 jQuery 1.5 或现代的东西,你难道不想要$.when(function1).then(function2);(没有调用函数的括号)?
2021-03-21 18:31:03
但这是一个有效的例子吗?什么被推迟?您正在立即执行 function1 和 function2。(我不是原评论者。)
2021-03-29 18:31:03
这对我来说根本不起作用。function1 和 function2 都在完全相同的时间执行(人眼可以观察到)。这是一个小例子:jsfiddle.net/trusktr/M2h6e
2021-04-01 18:31:03
几年后才看到这些评论。 function1应该返回一个Promise。在这种情况下,它需要是实际执行的函数,而不是引用。resolve该Promise被调用时,则function2执行。假设function1有一个 ajax 调用,这很容易解释然后done回调将解决Promise。我希望这很清楚。
2021-04-02 18:31:03

试试这个 :

function method1(){
   // some code

}

function method2(){
   // some code
}

$.ajax({
   url:method1(),
   success:function(){
   method2();
}
})
在测试了其他几个解决方案后,终于对我有用了:) 谢谢@TuanTruong!!您可以添加一些文本以使此答案对遇到相同问题的其他用户更有用。
2021-03-24 18:31:03

这个答案使用标准promises的 JavaScript 特性ECMAScript 6如果您的目标平台不支持promises,请使用PromiseJs对其进行polyfill

Promise 是一种在 JavaScript 中处理异步操作的新方法(而且更好):

$('a.button').click(function(){
    if (condition == 'true'){
        function1(someVariable).then(function() {
            //this function is executed after function1
            function2(someOtherVariable);
        });
    }
    else {
        doThis(someVariable);
    }
});


function function1(param, callback) {
    return new Promise(function (fulfill, reject){
        //do stuff
        fulfill(result); //if the action succeeded
        reject(error); //if the action did not succeed
    });
} 

对于这个简单的例子来说,这似乎是一个很大的开销,但对于更复杂的代码,它比使用回调要好得多。您可以使用多个then语句轻松链接多个异步调用

function1(someVariable).then(function() {
    function2(someOtherVariable);
}).then(function() {
    function3();
});

您还可以轻松包装 jQuery deferrds(从$.ajax调用中返回):

Promise.resolve($.ajax(...params...)).then(function(result) {
    //whatever you want to do after the request
});

正如@charlietfl 所指出的,jqXHR返回对象$.ajax()实现了Promise接口。所以其实没必要用a包裹Promise,直接使用即可:

$.ajax(...params...).then(function(result) {
    //whatever you want to do after the request
});
Promise.resolve包装$.ajax是反模式,因为$.ajax返回可Promise的
2021-03-22 18:31:03
实际上在 jQuery 版本 3+ 中是 Promises A+ 兼容的。不管$.ajax.then是不是新的
2021-04-09 18:31:03
@charlietfl 但它不是实际的Promise,它只是实现了接口。我不确定在将 real 传递Promise给它的then方法时它的行为,或者Promise.all如果将 ajqXHR和 aPromise传递给它会做什么。为此,我需要做进一步的测试。但感谢您的提示,我会将其添加到答案中!
2021-04-11 18:31:03

或者您可以在一个函数完成时触发自定义事件,然后将其绑定到文档:

function a() {
    // first function code here
    $(document).trigger('function_a_complete');
}

function b() {
    // second function code here
}

$(document).bind('function_a_complete', b);

使用这种方法,函数 'b' 只能在函数 'a' 之后执行,因为触发器仅在函数 a 执行完毕后才存在。

“从 jQuery 1.7 开始,.on() 方法是将事件处理程序附加到文档的首选方法。” api.jquery.com/bind
2021-04-01 18:31:03