首先我会说没有“最佳方式”,因为它们的行为都略有不同……其次,我要补充的是,这与其说是 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 函数应该是调用对象中包含的函数
选项 4 与选项 1 类似,不同之处在于您已命名函数(并且它们在当前范围内可用)并按名称调用它们。
我通常使用选项 2 或选项 4 之类的东西——但我希望您能看到它实际上取决于您尝试如何构建代码。
编辑:
回应关于Function.createDelagate() 的评论——它似乎只是一个ASP.NET 脚本资源中的助手;除了调用apply()(这是执行此操作的标准JS 方式——see MDN documentation here)之外,它什么也不做。它还可能在 ASP.NET 中的某个地方提供一些向后兼容性,但我不太确定!
这是我的 SP 环境中脚本资源文件中的函数代码:
Function.createDelegate = function(a, b) {
return function() {
return b.apply(a, arguments)
}
};
作为奖励,我在考虑如何使用executeQueryAsync,我意识到我实际上更频繁地使用它,就像选项 1 一样,使用 jQuery 延迟的承诺模式如下:
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();
}
然后你可以做一些不太像意大利面的事情,例如:
...
ctx.load(items);
getSPDataAsync(ctx).then(function() {
//do some stuff with the data when the promise resolves
});
以防万一有人关心! :)