jQuery Deferred/Promises 具有多个 SharePoint CAML 查询
jQuery Deferred/Promises with multiple SharePoint CAML Queries
大家好,我从三个单独的 SharePoint 列表进行了三个异步调用,每个查询都有一个成功回调 return 对象和数组。我希望在所有三个成功回调 return 之后执行另一个函数。我不确定如何让它与 jQuery deferreds 一起使用。我的代码如下。请帮助我了解如何使用 deferreds 来实现上面的 objective。
function managementMain() {
//From here I want to call the third function after executing
the managementQuery function.
outPutObj = managementQuery();
//Execute some third function with outPutObj:
third function(outPutObj);
}
function managementQuery() {
//CAML definition 1 here.
clContext.executeQueryAsync(Function.createDelegate(this, function () { var soObj = onSOQuerySucceeded(); }), Function.createDelegate(this, this.onQueryFailed));
//CAML definition 2 here.
clContext.executeQueryAsync(Function.createDelegate(this, function () { var poObj = onPOQuerySucceeded(); }), Function.createDelegate(this, this.onQueryFailed));
//CAML definition 3 here.
clContext.executeQueryAsync(Function.createDelegate(this, function () { var salesRepNamesList = onSalesRepNamesQuerySucceeded(); }), Function.createDelegate(this, this.onQueryFailed));
return {
soObj: soObj,
poObj: poObj,
salesRepList: salesRepNamesList
}
}
function onSOQuerySucceeded() {
//Do something with the SharePoint List and return an object called soObj.
}
function onSalesRepNamesQuerySucceeded() {
//Do something with the SharePoint List and return an array called salesRepNames.
}
function onPOQuerySucceeded() {
//Do something with the SharePoint List and return an object called poObj.
}
我遇到的问题是 soObj、poObj 和 salesRepNamesList 到时候可能 returned
管理查询函数 returns。因此,到执行第三个函数时,outPutObj 可能定义错误。请指教。谢谢
您基本上会创建 3 个延迟对象,每个异步请求一个。异步请求完成后,您将在延迟对象上调用 .resolve 方法
// query will return a promise
outputPromise = query();
// your third function needs to wait for the promise to resolve
// to ensure the wait, you use the .then() method on the promise above
outputPromise.then(function(outputObj) {
thirdFunction(outputObj);
});
function query() {
// Create deferred objects
var deferred1 = $.Deferred();
var deferred2 = $.Deferred();
clContext.executeQueryAsync(Function.createDelegate(this, function () {
var soObj = onSOQuerySucceeded();
deferred1.resolve(soObj);
}), Function.createDelegate(this, function () {
this.onQueryFailed();
deferred1.reject();
}));
clContext.executeQueryAsync(Function.createDelegate(this, function () {
var poObj = onPOQuerySucceeded();
deferred2.resolve(poObj);
}), Function.createDelegate(this, function() {
this.onQueryFailed();
deferred2.reject();
}));
// we must wait for all async ops to finish. to do this, we use the $.when() method
// the $.when() method returns a promise that is resolved with the return
// values of each deferred that was passed in. the then takes a callback
// function and will spread each resolved value over the callback function's arguments
return $.when(deferred1, deferred2).then(function(soObj, poObj) {
// create the output object in the format you specified
return {
soObj: soObj,
poObj: poObj
}
});
}
jQ Deferred 文档在这里:https://api.jquery.com/category/deferred-object/ 以备不时之需
附带说明一下,我强烈建议使用另一个 Promise 库,例如 bluebird 或 Q,而不是 jQuery 的 deferreds。它们符合广泛接受的 Promise/A+ 规范和随后的 ES2015 Promise 规范。 jQ 3 将有一个 Promises/A+ 兼容的延迟模式,但延迟模式不在 ES2015 中,你应该使用其他库提供的 Promise 模式。
首先,代码比需要的更复杂:
- 您可以清除
Function.createDelegate()
,它 (a) 不是标准的 javascript,(b) 没有必要,因为 none 应用它的函数使用 this
.微软有点顽皮,在他们的示例中包括 Function.createDelegate()
,因为它似乎与使用 clientContext.executeQueryAsync()
密切相关,但事实并非如此。
- 按照惯例,带有
Async
后缀的方法 应该 return 一个承诺,使您自己的 Deferreds 的 creation/resoltion 变得不必要。但是,Microsoft 又有点顽皮了,因为 clientContext.executeQueryAsync()
没有 遵循惯例。
其次,如果不首先聚合提供数据的承诺,则无法聚合异步派生的数据。如前所述,问题中的代码没有任何承诺的聚合。由于这是 jQuery,我们希望在代码中的某处看到 jQuery.when()
。
关于 promisification,最巧妙的方法始终是在最低级别进行 promisify - 在本例中为 clientContext.executeQueryAsync()
编写可重用的适配器函数,这 return 是所需的 promise。这将大大简化更高级别的功能 managementQuery()
。
这是承诺者:
clContext.executeQueryAsync_ = function() {
return $.Deferred(function(dfrd) {
clContext.executeQueryAsync(function(sender,args) {
dfrd.resolve({'sender':sender, 'args':args});
}, function(sender,args) {
dfrd.reject({'sender':sender, 'args':args})
});
}).promise();
};
现在,managementQuery()
可以写成没有 Deferreds 和没有 Function.createDelegate()
,如下所示:
function managementQuery() {
var query = clContext.executeQueryAsync_; // If clContext.executeQueryAsync() returns a promise, then assign clContext.executeQueryAsync() instead.
var promise1 = query(/* so params */);
var promise2 = query(/* po params */);
var promise3 = query(/* salesRep params */);
// Now aggregate the three promises with $.when(), and chain .then() to handle the delivered data.
return $.when(promise1, promise2, promise3)
.then(function(soObj, poObj, salesRepObj) {
// soObj, poObj and salesRepObj each have .sender and .args properties.
// Now the required object can be created and returned
// to become the data delivered (in a promise) by managementQuery().
return {
'soObj': onSOQuerySucceeded(),
'poObj': onPOQuerySucceeded(),
'salesRepList': onSalesRepNamesQuerySucceeded()
};
});
}
而managementMain()
可以写成:
function managementMain() {
return managementQuery()
.then(someOtherFunction) // someOtherFunction will be automagically passed the object created/returned above.
.fail(function(e) {
// Any promise rejection in managementQuery() or someOtherFunction will end up here.
console.log(e);
this.onQueryFailed();
});
}
大家好,我从三个单独的 SharePoint 列表进行了三个异步调用,每个查询都有一个成功回调 return 对象和数组。我希望在所有三个成功回调 return 之后执行另一个函数。我不确定如何让它与 jQuery deferreds 一起使用。我的代码如下。请帮助我了解如何使用 deferreds 来实现上面的 objective。
function managementMain() {
//From here I want to call the third function after executing
the managementQuery function.
outPutObj = managementQuery();
//Execute some third function with outPutObj:
third function(outPutObj);
}
function managementQuery() {
//CAML definition 1 here.
clContext.executeQueryAsync(Function.createDelegate(this, function () { var soObj = onSOQuerySucceeded(); }), Function.createDelegate(this, this.onQueryFailed));
//CAML definition 2 here.
clContext.executeQueryAsync(Function.createDelegate(this, function () { var poObj = onPOQuerySucceeded(); }), Function.createDelegate(this, this.onQueryFailed));
//CAML definition 3 here.
clContext.executeQueryAsync(Function.createDelegate(this, function () { var salesRepNamesList = onSalesRepNamesQuerySucceeded(); }), Function.createDelegate(this, this.onQueryFailed));
return {
soObj: soObj,
poObj: poObj,
salesRepList: salesRepNamesList
}
}
function onSOQuerySucceeded() {
//Do something with the SharePoint List and return an object called soObj.
}
function onSalesRepNamesQuerySucceeded() {
//Do something with the SharePoint List and return an array called salesRepNames.
}
function onPOQuerySucceeded() {
//Do something with the SharePoint List and return an object called poObj.
}
我遇到的问题是 soObj、poObj 和 salesRepNamesList 到时候可能 returned 管理查询函数 returns。因此,到执行第三个函数时,outPutObj 可能定义错误。请指教。谢谢
您基本上会创建 3 个延迟对象,每个异步请求一个。异步请求完成后,您将在延迟对象上调用 .resolve 方法
// query will return a promise
outputPromise = query();
// your third function needs to wait for the promise to resolve
// to ensure the wait, you use the .then() method on the promise above
outputPromise.then(function(outputObj) {
thirdFunction(outputObj);
});
function query() {
// Create deferred objects
var deferred1 = $.Deferred();
var deferred2 = $.Deferred();
clContext.executeQueryAsync(Function.createDelegate(this, function () {
var soObj = onSOQuerySucceeded();
deferred1.resolve(soObj);
}), Function.createDelegate(this, function () {
this.onQueryFailed();
deferred1.reject();
}));
clContext.executeQueryAsync(Function.createDelegate(this, function () {
var poObj = onPOQuerySucceeded();
deferred2.resolve(poObj);
}), Function.createDelegate(this, function() {
this.onQueryFailed();
deferred2.reject();
}));
// we must wait for all async ops to finish. to do this, we use the $.when() method
// the $.when() method returns a promise that is resolved with the return
// values of each deferred that was passed in. the then takes a callback
// function and will spread each resolved value over the callback function's arguments
return $.when(deferred1, deferred2).then(function(soObj, poObj) {
// create the output object in the format you specified
return {
soObj: soObj,
poObj: poObj
}
});
}
jQ Deferred 文档在这里:https://api.jquery.com/category/deferred-object/ 以备不时之需
附带说明一下,我强烈建议使用另一个 Promise 库,例如 bluebird 或 Q,而不是 jQuery 的 deferreds。它们符合广泛接受的 Promise/A+ 规范和随后的 ES2015 Promise 规范。 jQ 3 将有一个 Promises/A+ 兼容的延迟模式,但延迟模式不在 ES2015 中,你应该使用其他库提供的 Promise 模式。
首先,代码比需要的更复杂:
- 您可以清除
Function.createDelegate()
,它 (a) 不是标准的 javascript,(b) 没有必要,因为 none 应用它的函数使用this
.微软有点顽皮,在他们的示例中包括Function.createDelegate()
,因为它似乎与使用clientContext.executeQueryAsync()
密切相关,但事实并非如此。 - 按照惯例,带有
Async
后缀的方法 应该 return 一个承诺,使您自己的 Deferreds 的 creation/resoltion 变得不必要。但是,Microsoft 又有点顽皮了,因为clientContext.executeQueryAsync()
没有 遵循惯例。
其次,如果不首先聚合提供数据的承诺,则无法聚合异步派生的数据。如前所述,问题中的代码没有任何承诺的聚合。由于这是 jQuery,我们希望在代码中的某处看到 jQuery.when()
。
关于 promisification,最巧妙的方法始终是在最低级别进行 promisify - 在本例中为 clientContext.executeQueryAsync()
编写可重用的适配器函数,这 return 是所需的 promise。这将大大简化更高级别的功能 managementQuery()
。
这是承诺者:
clContext.executeQueryAsync_ = function() {
return $.Deferred(function(dfrd) {
clContext.executeQueryAsync(function(sender,args) {
dfrd.resolve({'sender':sender, 'args':args});
}, function(sender,args) {
dfrd.reject({'sender':sender, 'args':args})
});
}).promise();
};
现在,managementQuery()
可以写成没有 Deferreds 和没有 Function.createDelegate()
,如下所示:
function managementQuery() {
var query = clContext.executeQueryAsync_; // If clContext.executeQueryAsync() returns a promise, then assign clContext.executeQueryAsync() instead.
var promise1 = query(/* so params */);
var promise2 = query(/* po params */);
var promise3 = query(/* salesRep params */);
// Now aggregate the three promises with $.when(), and chain .then() to handle the delivered data.
return $.when(promise1, promise2, promise3)
.then(function(soObj, poObj, salesRepObj) {
// soObj, poObj and salesRepObj each have .sender and .args properties.
// Now the required object can be created and returned
// to become the data delivered (in a promise) by managementQuery().
return {
'soObj': onSOQuerySucceeded(),
'poObj': onPOQuerySucceeded(),
'salesRepList': onSalesRepNamesQuerySucceeded()
};
});
}
而managementMain()
可以写成:
function managementMain() {
return managementQuery()
.then(someOtherFunction) // someOtherFunction will be automagically passed the object created/returned above.
.fail(function(e) {
// Any promise rejection in managementQuery() or someOtherFunction will end up here.
console.log(e);
this.onQueryFailed();
});
}