我已经阅读了关于函数表达式与声明,回调,提升的分配,我得到了大部分内容的一般概念,但我想我不能完全掌握这个概念,因为下面的代码,让我发布代码和然后问真正的问题。
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请求的结果。我只是不完全理解代码执行流程是如何工作的,如果有人可以解释为什么底层函数不起作用以及如何让它工作我会很感激。
谢谢, 丹
答案 0 :(得分: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);
答案 1 :(得分: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