如何让ExecuteQueryAsync更加同步?

时间:2014-03-14 16:55:06

标签: javascript jquery sharepoint

Aight ..这个Sharepoint使用Javascript ..我正在使用警报来调试从内容编辑器Web部件运行的Javascript;该脚本位于Assets库中。

我明白了......" async"的全部要点函数调用是不等待调用完成....但我担心ExecuteQueryAsync中的操作将在未来操作依赖的情况下完成,从而导致错误。

我很确定,因为我的警报IN&警告反击"向后"我确实得到了我的异步行为。我试过" ExecuteQuery"没有" Async"部分......惨遭失败。

有人想在返回OBJ功能之前,朝着正确的方向努力让我的ONSUCCESS函数中的活动完成吗?

function One()
{
alert("in ONE");
OBJ();
alert("back from Obj, in One Again");
}

function OBJ(){
alert("in OBJ");
 var clientContext = null; 
 var currentweb = null; 
        clientContext = new SP.ClientContext.get_current(); 
        web = clientContext.get_web(); 
        var Questionlist = web.get_lists().getByTitle("Exam Objectives"); 
        var camlQuery = new SP.CamlQuery();
        var q = "";    //camlQuery text in q to limit colls returned, empty string returns all
        camlQuery.set_viewXml(q); 
        this.listItems = Questionlist.getItems(camlQuery); 

        clientContext.load(listItems);
         clientContext.executeQueryAsync(Function.createDelegate(this, this.onListItemsLoadSuccessObj), Function.createDelegate(this,         this.onQueryFailed)); 
 alert("leaving OBJ");    //THIS ALERT FIRES BEFORE THE ALERT BELOW********
 }

function onListItemsLoadSuccessObj(sender, args) { 
 var listItemInfo = '';
 var oListItem = null;
var listItemEnumerator = listItems.getEnumerator();

while (listItemEnumerator.moveNext()) {
    oListItem = listItemEnumerator.get_current();
    listItemInfo += '\nID: ' + oListItem.get_id() + 
        '\nTitle: ' + oListItem.get_item('Title');
}

alert(listItemInfo.toString());  //THIS ALERT FIRES AFTER THE ALERT ABOVE*********     
}

2 个答案:

答案 0 :(得分:8)

你想看看Promises。 Scot Hillier在这里有一篇很好的文章:http://www.shillier.com/archive/2013/03/04/using-promises-with-the-javascript-client-object-model-in-sharepoint-2013.aspx但基本上它们允许你编写这样的代码:

doSomething()
.then(doSomethingElseWhenThatsDone, orHandleAnError)
.then(doYetAnotherThingWhenThatsDone, orHandleAnError);

你打电话来做你的工作(doSomething,doSomethingElseWhenThatsDone,doYetAnotherThingWhenThatsDone)看起来像这样:

function doSomething(){
    //set up some JSOM stuff
    var dfd = $.Deferred();
    context.executeQueryAsync(
        function () {
            dfd.resolve();
        }, function (sender, args) {
            dfd.reject(sender, args, errorMsg);
        });
    return dfd.promise()
}

每个都设置一个JQuery Deferred对象并返回它的Promise。 Promise导致调用函数等待,直到Promise被解析或拒绝(分别在ExecuteQueryAsync的成功或失败回调中)。

你可以用承诺做更多事情,这几乎没有表面上的痕迹。通常,它们允许您在必要时强制以同步方式执行异步调用。

HTH,

戴夫

答案 1 :(得分:0)

这是预期的行为。 executeQueryAsync来电是非阻止的。这意味着它将在那里停留足够长的时间以便在继续执行其余代码之前启动查询。您可以注册成功和失败回调来处理查询结果。

如果您要在查询完成后执行代码,则应将其移至这些回调中。