Javascript AJAX工作流:如何安排这些函数的执行顺序?

Javascript AJAX工作流:如何安排这些函数的执行顺序?,javascript,ajax,Javascript,Ajax,我正试图找出让函数按正确顺序执行的最佳方法 我有3个功能 功能1-通过JSON将选项喷射到SELECT中,并将其标记为已选择 功能2-将选项喷射到第二个选择中,并将其标记为已选择 函数3-从上面的选择中获取值以及一些额外的输入值,AJAX GET生成JSON数据,该数据被读取并填充到表中 使用JQuery Onload,我执行: function1(); function2(); function3(); 我发现function3在SELECTs填充选项之前执行,因此该表没有结果,因为GET中

我正试图找出让函数按正确顺序执行的最佳方法

我有3个功能

功能1-通过JSON将选项喷射到SELECT中,并将其标记为已选择
功能2-将选项喷射到第二个选择中,并将其标记为已选择
函数3-从上面的选择中获取值以及一些额外的输入值,AJAX GET生成JSON数据,该数据被读取并填充到表中

使用JQuery Onload,我执行:

function1();
function2();
function3();
我发现function3在SELECTs填充选项之前执行,因此该表没有结果,因为GET中发送的值为空

我知道这可能是一个非常简单的问题,可能有十几种方法可以实现这一点,但基本上我需要最好的编码方法,以便只有在函数1和2完成时,函数3才能运行

我首先学习了JQuery的基础知识,然后通过后门进入了Javascript


感谢您的帮助。

调用
function1
内部的
function2
function3
内部的
function2

不清楚为什么f1和f2在f3之前执行

另外,您使用的是首选$(document).ready()还是onload的一些变体


如果您提供一个可复制的测试用例,这可能会有所帮助。

Javascript同步执行,这意味着
function3
必须等待
function2
完成,而
function1
必须在执行之前完成

例外情况是当您运行异步代码时,如
setTimeout
setInterval
或异步AJAX请求

任何依赖于此类异步代码完成的后续代码都需要以这样一种方式进行调用,即在异步代码完成之前它不会执行

对于
setTimeout
,您可以将下一个函数调用放在传递给
setTimeout
的函数末尾

在AJAX调用的情况下,您可以将下一个函数调用放在一个回调中,该回调在完成请求时触发

如果不希望每次都执行后续函数,可以修改函数以接受在异步代码末尾调用的函数参数

比如:

function function1( fn ) {
    setTimeout(function() {
        // your code 
        // Call the function parameter if it exists
        if( fn ) {
            fn();
        }
    }, 200);
}

function function2() {
    // some code that must wait for function1
}
加载:

// Call function1 and pass function2 as an argument
function1( function2 );

// ...or call function1 without the argument
function1();

// ...or call function2 independently of function1
function2();
fun3()将仅在两个都准备好后运行。它可能会运行两次。您可以使用fun3()中的锁修复此问题。您需要一个单例来保证它正常工作

var select1ready = false, select2ready = false;

fun1()
{
   // do stuff
   select1ready = true;
   fun3();
}

fun2()
{
  // do stuff
  select2ready = true;
  fun3();
}

fun3()
{
   if (select1ready && select2ready)
   {
   }
}


fun1();
fun2();

我建议您使用Promissions库。您可以像其他答案所建议的那样破解简单的解决方案,但随着应用程序的增长,您会发现您正在进行越来越多的此类破解。承诺旨在解决处理异步调用时的此类问题

CommonJS项目中有您应该签出的项目。这里是一段时间前与其他解决方案的链接。了解有关中的承诺的更多信息。整个视频都很好,但请跳到刚刚过了一半的时候

我正在使用图书馆,因为它适合我的需要。但其他实现也有优势。它允许您非常轻松地执行
序列

// Initialize Application
Futures.sequence(function (next) { 
    // First load the UI description document
    loadUI(next);  // next() is called inside loadUI
})
.then(function(next) {
    // Then load all templates specified in the description
    loadTemplates(next); // next() is called inside loadTemplates
})
.then(function(next) {
    // Then initialize all templates specified in the description
    initTemplates();
});
更强大的功能是当您需要将
异步事件连接在一起,并在所有其他异步事件完成后执行另一个操作时。下面是一个示例(未测试),它将加载一组HTML文件,然后仅在所有HTML文件都完成加载后执行操作:

var path = "/templates/",
    templates = ["one.html","two.html","three.html"],
    promises = [];

$.each(templates, function(i,name) {
    promises[i] = Futures.promise();
    var $container = $("<div>");
    $container.load(path+name, function(response,status,xhr) {
        promises[i].fullfill();
    }
});

Futures.join(promises, {timeout: 10000}) // Fail if promises not completed in 10 seconds
    .when(function(p_arr) {
        console.log("All templates loaded");
    })
    .fail(function(p_arr) {
        console.log("Error loading templates");
    });
var path=“/templates/”,
templates=[“one.html”、“two.html”、“three.html”],
承诺=[];
$。每个(模板、函数(i、名称){
承诺,许诺【例】承诺,许诺;
var$container=$(“”);
$container.load(路径+名称、函数(响应、状态、xhr){
承诺[i].fullfill();
}
});
Futures.join(promises,{timeout:10000})//如果承诺没有在10秒内完成,则失败
.何时(功能(p_arr){
log(“加载的所有模板”);
})
.失败(功能(p_arr){
log(“加载模板时出错”);
});
这对你的应用程序来说可能有些过分。但是如果应用程序的复杂性在增长,那么从长远来看,使用承诺将对你有所帮助


我希望这会有所帮助!

这将对我的首次加载执行有效,但我想稍后调用这些函数,不希望它们每次都执行辅助函数。在所有3个函数的作用域之外创建2个变量,并将它们设置为false,在函数1和函数2内部启动函数2和函数3时将它们设置为true如果变量设置为false,则只调用后者。@尼尔·伯顿,您在这些函数中是否使用了任何ajax调用。如果您使用的是ajax调用,它们是异步调用,则函数启动ajax并移动到下一个函数。较新的API fore Futures.Sequence是。then(函数(下一个,arg1,arg2,…{next(新arg1,新arg2,…)})@CoolAJ86-感谢您的澄清,我刚刚编辑了答案。请注意,
loadUI
loadTemplates
进行异步AJAX调用,因此我将
next
传递给他们,他们在完成后实际调用
next()