AJAX工作流程:如何订购这些功能的执行?

时间:2010-11-06 15:11:06

标签: javascript ajax

我正在尝试找出以正确顺序执行函数的最佳方法。

我有3个功能

功能1 - 通过JSON将OPTION喷射到SELECT中并将它们标记为已选择
功能2 - 将OPTIONS喷射到第二个SELECT中并将它们标记为选中
function 3 - 从上面的SELECT中获取值以及一些额外的INPUT值,AJAX GET是否产生JSON数据,读取并填充表格。

使用JQuery Onload,我执行:

function1();
function2();
function3();

我发现在使用OPTIONS填充SELECT之前,function3正在执行,因此该表没有结果,因为GET中发送的值是空白的。

我知道这可能是一个非常简单的问题,并且可能有十几种方法可以实现这一点,但基本上我需要最好的方法对其进行编码,以便function3仅在function1和2完成时运行。

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

感谢您的协助。

5 个答案:

答案 0 :(得分:1)

Javascript同步执行,这意味着function3必须等待function2完成,必须等待function1完成才能执行。

例外情况是您运行异步代码,例如setTimeoutsetInterval或异步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
}

的onload:

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

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

// ...or call function2 independently of function1
function2();

答案 1 :(得分:1)

我建议您使用 Promises 库。你可以像其他答案一样破解简单的解决方案,但随着你的应用程序的增长,你会发现你正在做越来越多的这些黑客攻击。 Promise旨在解决处理异步调用时的这些问题。

CommonJS项目有several Promises proposals,您应该查看。这是question I asked on SO about Promises一段时间以及其他解决方案的链接。在this Douglas Crockford video了解有关Promise的更多信息。整个视频都很好,但跳到承诺的一半。

我目前正在使用FuturesJS库,因为它符合我的需要。但是其他实现也有优势。它允许您非常轻松地执行sequences

// 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();
});

更强大的是当您需要join异步事件并在所有其他异步事件完成时执行其他操作时。这是一个示例(未经测试),它将加载一堆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");
    });

这可能对您的应用程序来说太过分了。但是如果应用程序的复杂性越来越高,那么使用promises会对您产生长期的帮助。

我希望这有帮助!

答案 2 :(得分:0)

function2内部调用function1,在function3内调用function2

答案 3 :(得分:0)

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

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

如果您提供可重现的测试用例可能会有所帮助。

答案 4 :(得分:0)

fun3()只会在两者准备好后才会运行。它可能会运行两次。你可以用fun3()里面的锁来解决这个问题,你需要一个Singleton才能保证它能正常工作。

var select1ready = false, select2ready = false;

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

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

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


fun1();
fun2();