如何多次调用executeQueryAsync

时间:2015-07-09 09:46:57

标签: javascript sharepoint callback

首先抱歉糟糕的标题,只是想不出更好。

我是JavaScript的新手,这可能是我没有得到这个的唯一原因 - 请不要爆炸我。

我想要做的只是使用JavaScript客户端对象模型从Sharepoint站点查询多个 Sharepoint列表(甚至可能多次)。我能够在网上找到许多工作示例,如何从列表中检索数据并使用它。但我对异步和回调概念如此陌生,以至于我无法将概念转移到我的需要。 我实际上必须复制所有变量和函数x次吗?

以下是我拨打一个电话的原因:

var listAItems;

$(document).ready(function() {      
  ExecuteOrDelayUntilScriptLoaded(LoadChartData, "sp.js");
});

function LoadChartData() {
  context = SP.ClientContext.get_current();
  var listA = context.get_web().get_lists().getByTitle("ListA");
  var camlQuery = SP.CamlQuery.createAllItemsQuery();
  this.listAItems = listA.getItems(camlQuery);

  context.load(listAItems);
  context.executeQueryAsync(ReadListAItemSucceeded, ReadListItemFailed);
}

function ReadListAItemSucceeded(sender, args) {
  var listAItemsCollection = listAItems.getEnumerator();

  while (listAItemsCollection.moveNext()) {
    var listAItem = listAItemsCollection.get_current();
    //do something with each listItem
  }
}

function ReadListItemFailed(sender, args) {
  alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}

我最终复制了所有代码以使其运行,但这不是可行的方法,因为它只是一团糟 - 必须有一个实际的设计。

var listAItems;
var listBItems;

$(document).ready(function() {      
  ExecuteOrDelayUntilScriptLoaded(LoadChartData, "sp.js");
});

function LoadChartData() {
  context = SP.ClientContext.get_current();
  var listA = context.get_web().get_lists().getByTitle("ListA");
  var camlQuery = SP.CamlQuery.createAllItemsQuery();
  this.listAItems = listA.getItems(camlQuery);

  context.load(listAItems);
  context.executeQueryAsync(ReadListAItemSucceeded, ReadListItemFailed);

  context2 = SP.ClientContext.get_current();
  var listB = context.get_web().get_lists().getByTitle("ListB");
  var camlQuery2 = SP.CamlQuery.createAllItemsQuery();
  this.listBItems = listB.getItems(camlQuery2);

  context2.load(listBItems);
  context2.executeQueryAsync(ReadListBItemSucceeded, ReadListItemFailed);
}

function ReadListAItemSucceeded(sender, args) {
  var listAItemsCollection = listAItems.getEnumerator();

  while (listAItemsCollection.moveNext()) {
    var listAItem = listAItemsCollection.get_current();
    //do something with each listItem
  }
}

function ReadListBItemSucceeded(sender, args) {
  var listBItemsCollection = listBItems.getEnumerator();

  while (listBItemsCollection.moveNext()) {
    var listBItem = listBItemsCollection.get_current();
    //do something with each listItem
  }
}

function ReadListItemFailed(sender, args) {
  alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}

为什么我要查询多个列表是显而易见的,查询同一列表的原因是提供不同的CAML表达式,例如不同的条件。

非常感谢您提前!

1 个答案:

答案 0 :(得分:5)

异步概念并不困难,你必须思考:"做到这一点,当你完成调用这个函数"时,这个概念就应用于变量的可见性,在javascript中这称为closure

在你的代码中你可以这样做(警告我没有测试下面的代码)

$(document).ready(function() {      
  ExecuteOrDelayUntilScriptLoaded(loadChartData, "sp.js");
});

function loadChartData() {
    loadListData("listA", listASuccess, globalError);
    loadListData("listB", listBSuccess, globalError);
}

function loadListData(listName, onSuccess, onFail) {
  context = SP.ClientContext.get_current();
  var list = context.get_web().get_lists().getByTitle(listName);
  var camlQuery = SP.CamlQuery.createAllItemsQuery();
  var listItems = list.getItems(camlQuery);

  context.load(listAItems);

  context.executeQueryAsync(
        function(sender, args) { 
            // listItem is defined on same closure, you do not need to declare globally
            onSuccess(listItems); 
        }, 
        onFail
  );

}

function listASuccess(data) {

  var listAItemsCollection = data.getEnumerator();

  while (listAItemsCollection.moveNext()) {
    var listAItem = listAItemsCollection.get_current();
    //do something with each listItem
  }

  // You can use also forEach like this
  // data.forEach(function(listItem) {
  //    //do something with each listItem
  // });
}

function listBSuccess(data) {

  var listBItemsCollection = data.getEnumerator();

  while (listBItemsCollection.moveNext()) {
    var listBItem = listBItemsCollection.get_current();
    //do something with each listItem
  }

  // You can use also forEach like this
  // data.forEach(function(listItem) {
  //    //do something with each listItem
  // });
}

function globalError(sender, args) {
  alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
}

参见closureforEach