我想将使用itemFileReadStore的查询结果保存到名为boxes的数组中,但返回值为空(可能是因为fetch是异步运行的)。
gotItems函数按照我的意愿构建数组,但我不能将它返回给自己任何用途!我可以将其余的功能构建到gotItems部分,但这会使我的代码不合适。
如何从gotItems函数返回我的JavaScript中常用的数组?
function getContentFile() {
contentStore = new dojo.data.ItemFileReadStore({
url: '../config/content.json',
preventCache : true
});
var boxes = new Array();
contentStore.fetch({query: {partner : 'enabled'}, onItem: gotItems });
return boxes;
}
function gotItems(item ) {
boxes.push( contentStore.getValue(item,'title') );
console.log( boxes );
return boxes;
}
dojo.addOnLoad( function() {
boxes = getContentFile();
console.log(boxes);
fadeIn('header', 500, 0);
});
答案 0 :(得分:0)
欢迎来到异步操作的世界。
你需要使用“延续式”编程来完成它。 ItemFileReadStore的提取操作是异步的 - 正如您已经知道的那样,将gotItems
延续传递给它。
contentStore.fetch({query: {partner : 'enabled'}, onItem: gotItems })
会立即返回。此时boxes
将为空(因为JavaScript是单线程的)。 gotItems
在数据到达后执行,后续执行传递给dojo.addOnLoad
返回的函数。
您必须输入处理代码:
console.log(boxes);
fadeIn('header', 500, 0);
在延续gotItems
内部。例如,像:
function gotItems(item ) {
var boxes = [];
dojo.forEach(item, function(box) {
boxes.push( contentStore.getValue(box,'title') );
});
console.log(boxes); // You probably need to store "boxes" somewhere instead of just logging it
fadeIn('header', 500, 0);
}
此外,传递给onItems
的数据是一个数组,因此您需要迭代它。
答案 1 :(得分:0)
当函数返回时,您无权访问结果,因为您猜对了,fetch操作是异步执行的。
您可以将使用结果的代码放在gotItems()
函数中(由Stephen回答),也可以使用Deferreds和Promises。恕我直言,这是一个更好的选择,因为它可以让你更好地组织你的代码(一旦习惯了处理promises的习惯用法,代码读取更自然),它允许你透明地执行同步和异步操作。
在您的情况下,涉及延迟的可能解决方案如下:
function getContentFile() {
contentStore = new dojo.data.ItemFileReadStore({
url: '../config/content.json',
preventCache: true
});
var dfd = new dojo.Deferred();
var boxes = new Array();
contentStore.fetch({
query: { partner : 'enabled' },
onItem: function(item) {
boxes.push( contentStore.getValue(item,'title') );
},
onComplete: function() {
// resolve the promise and execute the function in then()
dfd.callback(boxes);
}
});
return dfd;
}
dojo.addOnLoad( function() {
getContentFile().then(function(boxes) {
console.log(boxes);
fadeIn('header', 500, 0);
});
});