Optimal/preferred way to call 'SP.ClientContext.executeQueryAsync' in SharePoint

左心房为你撑大大i 提交于 2019-12-03 03:02:42

First I would say there is no 'optimal way' as these all just behave somewhat differently... Second, I would add this isn't so much a SharePoint or executeQueryAsync specific thing as it is a JS thing in general...

Next we need to understand that executeQueryAsync expects two functions as arguments: the first is a function to perform if executeQueryAsync succeeds, the second is a function to perform if the method encounters an error. These functions are passed parameters (from executeQueryAsync, not from your JS) representing the sending object as well as an arguments object that can have some data (args.get_message() and args.get_stackTrace() are common in the case of a failed call)

In your 'Option 1' example, executeQueryAsync is given two anonymous functions, you won't be able to re-use them anywhere, but if the behavior is simple this may be sufficient.

In Option 2 you use the createDelegate method to give the success and failure callbacks a context -- this speaks to scoping within JavaScript; if you need to reference a variable that is only accessible in the function that calls executeQueryAsync, you'll need to use this sort of pattern so that this within the callback references the function that called executeQueryAsync instead of the success or failure function that you're now in. You can think of creating a delegate as the calling function calling on some other function, but saying 'I want that function to be able to see what I can see no matter where it's located at within the code.' This may all seem a bit arcane, but such is scoping within JavaScript... You could completely circumvent the need for doing this by referencing variables at higher scope levels (say inside of a function that contains the calling method as well as the success and failure methods)

Option 3 is just like Option 2, except it just specifies that the _onSucceed or _onFail functions should be the ones that are contained within the calling object

Option4 is just like Option 1, except that you've named the functions (and that they are available within the current scope) and are calling them by name.

I usually use something like option 2, or option 4 -- but I hope you can see that it really just depends on how you're trying to structure your code.

EDIT: In response to a comment about Function.createDelagate() -- It seems to just be a helper in an ASP.NET script resource; it does nothing other than calling apply() (which is the standard JS way of doing this -- see MDN documentation here). It might also provide some backward compatibility somewhere within ASP.NET, but I'm not really sure!

Here is the code for the function from a script resource file in my SP environment:

Function.createDelegate = function(a, b) {
    return function() {
        return b.apply(a, arguments)
    }
};

And as a bonus, I was thinking about how I use executeQueryAsync and I realized that I actually use it more often like option 1, with a promise pattern using jQuery deferreds like this:

function getSPDataAsync(context) {
    var deferred = $.Deferred();
    context.executeQueryAsync(function(sender, args) {
        deferred.resolve(sender, args);
    }, function(sender, args) {
        deferred.reject(sender, args);
    });
    return deferred.promise();
}

Then you can do things a little less-spaghetti-like, such as:

...
ctx.load(items);
getSPDataAsync(ctx).then(function() {
    //do some stuff with the data when the promise resolves
});

Just in case anyone cares! :)

Please try the below answer...this should help..Below code uses the context.ExecutequeryAsync method but since the items are captured separately on a string array there should not be any issues with respect to asynchronous behavior..

<style>
table { table-layout: fixed; }
td { width: 50%; }
</style><script type="text/javascript">
    function ShowselectedItems() {
        var ctx = new SP.ClientContext.get_current();
                web = ctx.get_web();
         if (ctx != undefined && ctx != null) {
            var listId = SP.ListOperation.Selection.getSelectedList();
                        var oList = ctx.get_web().get_lists().getByTitle('Testform'); // Put your list name here        
            var selectedItems = SP.ListOperation.Selection.getSelectedItems(ctx);
                        var camlquerystr = '';
                      if(selectedItems.length > 0){
                        if(selectedItems.length == 1)
                        {
                            camlquerystr += '<Where><Eq><FieldRef Name=\'ID\'/><Value Type=\'Number\'>' + selectedItems

[0].id + '</Value></Eq></Where>';
                        }
                        else if(selectedItems.length == 2)
                        {
                            camlquerystr += '<Where><Or><Eq><FieldRef Name=\'ID\'/><Value Type=\'Number\'>' + selectedItems

[0].id + '</Value></Eq><Eq><FieldRef Name=\'ID\'/><Value Type=\'Number\'>' + selectedItems[1].id + 

'</Value></Eq></Or></Where>';
                        }
                        else
                        {
                        var i;
                        camlquerystr += '<Where>';
                        for (i = 0; i < selectedItems.length - 1; i++) {
                               camlquerystr += '<Or><Eq><FieldRef Name=\'ID\'/><Value Type=\'Number\'>' + selectedItems

[i].id + '</Value></Eq>';
                        }
                        camlquerystr += '<Eq><FieldRef Name=\'ID\'/><Value Type=\'Number\'>' + selectedItems[i].id + 

'</Value></Eq>';
                        for (i = 0; i < selectedItems.length - 1; i++) {
                               camlquerystr += '</Or>';
                        }
                        camlquerystr += '</Where>';
                        }
                       }
                       else
                       {
                           alert('Please select your item');
                           retrun;
                       }
                        var camlQuery = new SP.CamlQuery();
                        camlQuery.set_viewXml('<View><Query>' + camlquerystr + '</Query></View>');
                        this.collListItem = oList.getItems(camlQuery);

                        ctx.load(collListItem, 'Include(Id, Title,Name,First_x0020_Name,Last_x0020_Name)');
                        ctx.executeQueryAsync(Function.createDelegate(this, this.success), Function.createDelegate(this, 

this.failed));
         }
       }

        function success() {
 var listItemInfo = '';
            var headstr = "<html><head><title></title></head><body>";
            var footstr = "</body>";
            var content;
    var listItemEnumerator = collListItem.getEnumerator();

    while (listItemEnumerator.moveNext()) {
        var oListItem = listItemEnumerator.get_current();
        content += "<table border='1' width='100%' style='table-layout: fixed;'><tr><td>Title:</td><td>" + oListItem.get_item('Title') + "</td></tr><tr><td>Name:</td><td>" + oListItem.get_item('Name') + "</td></tr><tr><td>First Name:</td><td>" + oListItem.get_item('First_x0020_Name') + "</td></tr><tr><td>LastName:</td><td>" + oListItem.get_item('Last_x0020_Name') + "</td></tr></table><br/><br/>";

    }

 w = window.open("", "_blank", "k");
                 w.document.write(headstr + content + footstr);
                 w.print();
        }

        function failed(sender, args) {
            alert('failed. Message:' + args.get_message());
        }        
</script><a href="#" onclick="javascript:ShowselectedItems();">Show Items</a>​​​​​
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!