0

我已经阅读了有关函数表达式与声明、回调、提升的分配,并且我对其中的大部分内容有了大致的了解,但我想由于下面的代码,我不能完全掌握这个概念,让我发布代码然后问真正的问题。

    var url = "beverages.txt";


   var GridModel = function () {
        this.items = ko.observableArray();
        var me = this;
        $.ajax({
            datatype: 'json',
            url: "beverages.txt"
        }).done(function (data) {
            debugger;
            var jsonData = $.parseJSON(data);
            me.items(jsonData);
        });
    };


    var model = new GridModel();

    // prepare the data
    var source =
    {
        datatype: "observablearray",
        datafields: [
            { name: 'name' },
            { name: 'type' },
            { name: 'calories', type: 'int' },
            { name: 'totalfat' },
            { name: 'protein' },
        ],
        id: 'id',
        localdata: model.items
    };

    var dataAdapter = new $.jqx.dataAdapter(source);

    $("#grid").jqxGrid(
    {
        width: 670,
        source: dataAdapter,
        theme: 'classic',
        columns: [
          { text: 'Name', datafield: 'name', width: 250 },
          { text: 'Beverage Type', datafield: 'type', width: 250 },
          { text: 'Calories', datafield: 'calories', width: 180 },
          { text: 'Total Fat', datafield: 'totalfat', width: 120 },
          { text: 'Protein', datafield: 'protein', minwidth: 120 }
        ]
    });

    ko.applyBindings(model);
});

好的,所以这段代码工作正常,它通过 var model = new GridModel(); 调用 ajax 请求。问题是,如果我添加一个调试器;var model = new GridModel(); 之后的语句 它失败。此外,ajax 请求中的调试器语句不会触发,但是如果我在 var model = new GridModel(); 之后删除调试器语句 然后 ajax 触发,我可以调试请求。为什么附加调试器会失败,是因为 var GridModel 是一个表达式。

基本上我想做的是创建一个我可以调用的声明函数,当ajax请求完成时我返回observableArray我。如果我改变这样的功能

  function GridModel (param1,param2) {
            this.items = ko.observableArray();
            var me = this;
            $.ajax({
                datatype: 'json',
                url: "beverages.txt"
            }).done(function (data) {
                debugger;
                var jsonData = $.parseJSON(data);
                me.items(jsonData);
            });
            return me
        };

然后我希望能够像这样调用该函数 var myitems = GridModel(param1,param2) 期望 myitems 现在将保存 ajax 请求的结果。我只是不完全理解代码执行流程是如何工作的,如果有人能解释为什么底部功能不起作用以及如何让它工作,我将不胜感激。

谢谢,丹

4

2 回答 2

3

如果您有一个异步操作(如 Ajax 请求),并且其他一切都取决于其结果,请从回调恢复您的程序流程。您不能使用return语句,它仅适用于同步代码。

您可能需要修改GridModel构造函数以将回调作为参数:

var GridModel = function (callback) {
    this.items = ko.observableArray();
    $.ajax({
        datatype: 'json',
        url: "beverages.txt"
    }).done(callback);
};

然后从回调内部恢复您的程序流程:

function resumeMyProgramFlow(data) {
    // Now you can use the data, resume flow from here
    debugger;
    var jsonData = $.parseJSON(data);
    model.items(jsonData);
    // etc.
}

并像这样实例化GridModel

var model = new GridModel(resumeMyProgramFlow);
于 2013-02-01T01:28:11.263 回答
2

返回时$.ajax(...).done(...),程序流程继续。

但是 ajax 调用还没有完成,因为它在后台向服务器发送数据并等待响应。这是异步部分。当响应最终从服务器到达时,.done(...)执行部分

function (data) {
    debugger;
    var jsonData = $.parseJSON(data);
    me.items(jsonData);
}

这是处理返回数据的位置和时间。

您所描述的var myitems = GridModel(param1,param2)是一种同步方法。它调用服务器停止进一步处理并等待响应。

虽然这是可能的,但它也会阻塞整个程序流程。这就是为什么 ajax 调用是异步的并且响应在回调函数中处理的原因。

您想要同步执行的操作

var myitems = GridModel(param1,param2);
// do something with myitems

以这种方式异步完成

$.ajax(...).done(function(data) {
    // 1. do something with myitems
});

// 2. this will run usually *before* number 1. above
于 2013-02-01T01:37:40.087 回答