2

不确定我的问题是否是主观/客观的,但作为一个 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") 我注意到在“发布状态:成功!”之前出现在我的控制台中的“测试”。

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

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

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

4

4 回答 4

3

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

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

于 2012-08-20T22:15:17.583 回答
1

AJAX 调用是异步的;这意味着$.post当请求完成时将执行公开的回调方法,但是一旦调用完成,您的 javascript 将继续执行$.post。如果你想在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");
        }
});
于 2012-08-20T22:18:00.647 回答
0

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

如果要一个一个地执行异步任务(如多米诺骨牌),则需要使用回调函数。

于 2012-08-20T22:17:16.507 回答
0

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

于 2012-08-20T22:20:06.377 回答