Javascript渲染.如何编写Javascript;t在函数调用结束之前继续执行代码

Javascript rendering. How to write Javascript so it doesn't continue executing code before a function call has ended

本文关键字:Javascript 继续 代码 执行 结束 渲染 何编写 函数调用      更新时间:2023-09-26

不确定我的问题是主观的还是客观的,但作为一名JavaScript新手,我经常遇到这个问题。所以我来了。

我习惯于编写C#,所以我的JavaScript结构看起来像C#。正因为如此,我认为这会带来问题;-)让我们举一个简单的例子,我今天再次遇到我的问题:

MyLibrary.fn.InitAddEntityForm = function () {
    $('a#btnAddEntity').click(function () {
            //post data and receive object with guid and isPersisted boolean
            var persistedObject = MyLibrary.fn.CheckAndSendAddEntityForm("name", "avatarurl.png");
            console.log("test");
            //check if persisted and go to next step
            if (persistedObject.isPersisted) {
                MyLibrary.fn.InitAddAnotherEntityForm(persistedObject.gdEntityId);
            } else {
                alert("Oops, something went wrong. Please call 911");
            }
    });
};

//////*****/////
//SOME FUNCTION THAT SENDS MY FORM AND RETURNS AN OBJECT WITH TRUE VALUE AND POSTED ENTITY ID
/////*****//////
MyLibrary.fn.CheckAndSendAddForm = function (txtName, ImageUrl) {
var postUrl = "/admin/add";
var persistedObject = new Object();
$.post(
    postUrl,
    { Name: txtName, ImageUrl: txtImageUrl},
    function (data) {
        if (data.Status == 200) {
            console.log("Post status:" + data.Message);
            persistedObject.isPersisted = true;
            persistedObject.gdEntityId = data.Data;
        } else if (data.Status == 500) {
            console.log("Failed to post entitiy");
        } else {
            console.log("Fault with Javascript");
        }
    }, "json"
);
return persistedObject;

};

好吧,就这样。一切看起来都很好,对吧?浏览器拒绝。我试着用firebug调试它,一行一行地在代码上循环,这样浏览器就可以完成我想要的任务:执行一个新函数,在向导中显示下一个面板。

在我的代码中放置了很多Console.logs()之后,我发现这一定是关于JavaScript中的计时问题。在C#中,代码逐行执行,但显然JavaScript没有。通过放置Console.log("test"),我注意到"test"出现在控制台中的"Post status:Success!"之前。

所以我的问题是,我应该如何编写JavaScript代码,以便控制浏览器执行代码的方式?我真的应该把下面的代码替换到CheckAndSendAddEntityForm()的末尾吗?

//check if persisted and go to next step
        if (persistedObject.isPersisted) {
            MyLibrary.fn.InitAddAnotherEntityForm(persistedObject.gdEntityId);
        } else {
            alert("fout");
        }

这就是我必须写JavaScript的方式:一个巨大的多米诺骨牌效应,还是我只是做错了什么?

$.post是AJAX调用的快捷方式,AJAX根据定义是异步的,这意味着它不会在继续处理之前等待响应。如果您将其切换到常规AJAX()方法,则可以将一个异步选项设置为false,这将使其行为如您所期望的那样。

或者,您也可以定义一个函数,在AJAX请求成功返回时执行,在该函数中您可以调用流程链中的下一步。

AJAX调用是异步的;这意味着$.post公开的回调方法将在请求完成时执行,但一旦对$.post的调用完成,javascript将继续执行。如果你想在ajax调用完成后做一些事情,你需要提供一个回调方法并做其他事情,例如:

MyLibrary.fn.CheckAndSendAddForm = function (txtName, ImageUrl, callback) {
var postUrl = "/admin/add";
var persistedObject = new Object();
$.post(
    postUrl,
    { Name: txtName, ImageUrl: txtImageUrl},
    function (data) {
        if (data.Status == 200) {
            console.log("Post status:" + data.Message);
            persistedObject.isPersisted = true;
            persistedObject.gdEntityId = data.Data;
        } else if (data.Status == 500) {
            console.log("Failed to post entitiy");
        } else {
            console.log("Fault with Javascript");
        }
        callback(); // This is where you return flow to your caller
    }, "json"
);
};

然后你这样调用:

var persistedObject = MyLibrary.fn.CheckAndSendAddEntityForm("name", "avatarurl.png", function()
{
        console.log("test");
        //check if persisted and go to next step
        if (persistedObject.isPersisted) {
            MyLibrary.fn.InitAddAnotherEntityForm(persistedObject .gdPronoId);
        } else {
            alert("Oops, something went wrong. Please call 911");
        }
});

JavaScript是单线程的。如果您有异步功能,一个简单的布尔信号量变量将有助于在某些进程运行时不允许调用函数。

如果您想一个接一个地执行异步任务(如domino行),则需要使用回调函数。

您遇到的是AJAX的"异步"部分。如果您想在物理上(如Javascript文件中的逐行),可以使用.success.pipe.donejQuery方法添加回调以进一步处理数据。如果可以的话,不要嵌入回调,否则你会得到你所说的"多米诺骨牌效应"。