Dojo 与ItemFileReadStore查询的异步混淆

Dojo 与ItemFileReadStore查询的异步混淆,dojo,Dojo,我想使用itemFileReadStore将查询结果保存到一个名为box的数组中,但返回值为空(可能是因为fetch是异步运行的) gotItems函数按照我的要求构建数组,但我无法将其返回给自己以供任何使用!我可以将我的其余功能构建到gotItems部分,但这会使我的代码变得不实用 如何从gotItems函数返回一个数组,以便在JavaScript中通用 function getContentFile() { contentStore = new dojo.data.ItemFileRea

我想使用itemFileReadStore将查询结果保存到一个名为box的数组中,但返回值为空(可能是因为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);
});

欢迎来到异步操作的世界

您需要使用“延续式”编程。ItemFileReadStore的获取操作是异步的——正如您通过向其传递
gotItems
continuation所知道的那样

contentStore.fetch({query:{partner:'enabled'},onItem:gotItems})
将立即返回。此时,您的
框将为空(因为JavaScript是单线程的)
gotItems
在数据到达后执行,随后将传递到
dojo.addOnLoad
的函数返回

您必须输入您的处理代码:

  console.log(boxes);
  fadeIn('header', 500, 0);
在continuation
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
的数据是一个数组,因此您需要对其进行迭代。

当函数返回时,您无法访问结果,因为正如您所猜测的,fetch操作是异步执行的

您可以将使用结果的代码放入
gottItems()
函数中(如Stephen所回答的),也可以使用延迟和承诺。IMHO,这是一个更好的选择,因为它可以让你更好地组织你的代码(一旦你习惯了处理承诺的习惯用法,代码就会读得更自然),并且它允许你透明地执行同步和异步操作

请参阅有关该主题的Dojo教程

在您的情况下,涉及延期的可能解决方案如下:

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);
  });
});