在SharePoint中调用"SP.ClientContext.executeQueryAsync"的最佳/首选方法

Nav*_*een 9 javascript sharepoint sharepoint-clientobject sharepoint-2013

我一直在学习客户端对象模型,并且遇到了这个方法executeQueryAsync.我发现有很多方法可以调用这种方法.我发现的一些是这些:

var context = new SP.ClientContext.get_current();

// Option 1
context.executeQueryAsync(
    function(sender, args){ },
    function(sender, args){ }
);

// Option 2
context.executeQueryAsync(
    Function.createDelegate(this, _onSucceed), 
    Function.createDelegate(this, _onFail)
);

// Option 3
context.executeQueryAsync(
    Function.createDelegate(this, this._onSucceed), 
    Function.createDelegate(this, this._onFail)
);

// Option 4
context.executeQueryAsync(_onSucceed, _onFail);
Run Code Online (Sandbox Code Playgroud)

哪种方式最优/最优?该声明还有什么作用Function.createDelegate这个功能文档似乎对我来说非常神秘.

Joh*_*n-M 16

首先我会说没有"最佳方式",因为这些只是表现得有点不同......其次,我想补充一点,这不是一个SharePoint或者executeQueryAsync特定的东西,因为它一般是JS的东西......

接下来我们需要理解,executeQueryAsync期望两个函数作为参数:第一个是executeQueryAsync成功时要执行的函数,第二个是在方法遇到错误时要执行的函数.这些功能是传递的参数(从executeQueryAsync代表发送对象为好,不从你的JS)作为参数对象,可以有一些数据(args.get_message()以及args.get_stackTrace()在呼叫失败的情况下是常见的)

在"选项1"示例中,executeQueryAsync给出了两个匿名函数,您将无法在任何地方重复使用它们,但如果行为很简单,这可能就足够了.

在选项2中,您使用该createDelegate方法为成功和失败回调提供上下文 - 这说明了JavaScript中的范围; 如果你需要引用一个只能在调用的函数中访问的变量executeQueryAsync,你需要使用这种模式,以便this在回调中引用调用的函数executeQueryAsync而不是你现在所处的成功或失败函数.你可以考虑创建一个委托作为调用其他函数的调用函数,但是说'我希望该函数能够看到我能看到的东西,无论它在代码中的位置.' 这可能看起来有点晦涩难懂,但这种情况在JavaScript中存在......你可以通过引用更高范围级别的变量来完全避免这样做的必要性(比如在包含调用方法的函数内部以及成功和失败方法)

选项3与选项2类似,只是它指定了_onSucceed或者_onFail函数应该是包含在调用对象中的函数

Option4与选项1类似,不同之处在于您已命名函数(并且它们在当前范围内可用)并按名称调用它们.

我通常使用类似选项2或选项4的东西 - 但我希望你能看到它实际上只取决于你如何构建代码.

编辑:回应评论Function.createDelagate()- 它似乎只是一个ASP.NET脚本资源的帮手; 它除了调用之外什么也没apply()做(这是标准的JS方式 - 请参阅此处的MDN文档).它也可能在ASP.NET中的某处提供一些向后兼容性,但我不确定!

以下是我的SP环境中脚本资源文件中的函数代码:

Function.createDelegate = function(a, b) {
    return function() {
        return b.apply(a, arguments)
    }
};
Run Code Online (Sandbox Code Playgroud)

作为奖励,我正在考虑如何使用executeQueryAsync,我意识到我实际上更常使用它,如选项1,使用jQuery延迟的promise模式,如下所示:

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();
}
Run Code Online (Sandbox Code Playgroud)

然后你可以做一些不那么像意大利面条的东西,比如:

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

万一有人关心!:)