如何使webEnumerator.moveNext等待executeQueryAsync查询执行
How to make webEnumerator.moveNext wait until executeQueryAsync query executes
在将控制权交还给webEnumerator.moveNext之前,我希望executeQueryAsync完成?
function onGetSubwebsSuccess(sender, args) {
var webEnumerator = webCollection.getEnumerator();
while (webEnumerator.moveNext()) {
alert("Loop 1");
web = webEnumerator.get_current();
this.props = web.get_allProperties();
context.load(this.props);
context.executeQueryAsync(Function.createDelegate(this, gotProperty), Function.createDelegate(this, failedGettingProperty));
}
}
function gotProperty() {
var myPropBag = this.props;
alert("Loop 2");
}
现在发生的事情是,我收到了两次"循环1"的警报,然后在"循环2"应该是这样的时候发出警报,
Loop 1
Loop 2
Loop 1
Loop 2
JavaScript I/O通常是非阻塞的。
context.executeQueryAsync
立即返回,因此它不断迭代原始循环。它在完成时接受回调。
你想要的是同步它。一个允许同步的概念是Promises。由于您已经用jQuery标记了这一点,您可以使用它的实现(或者更好的是,像Bluebird promise这样的强大实现)并执行以下操作:
// promisify executing the query in a context
function execute(context){
var d = $.Deferred();
context.executeQueryAsync(function(v){ return d.resolve(v)},
function(e){ return d.reject(v)});
return d.promise();
}
function onGetSubwebsSuccess(sender, args) {
var webEnumerator = webCollection.getEnumerator();
return $.when(1).then(function iterate(){ // start an empty promise
if(!webEnumerator.moveNext()) return ; // done iterating
alert("Loop 1"); // console.log is better for this though
var web = webEnumerator.get_current();
var props = web.get_allProperties();
context.load(this.props);
return execute(context).then(function (result){
alert("Loop 2");
alert(result); // do whatever you want with the result of the query
return iterate(); // loop
});
});
}
使用像Bluebird这样的更强的promise库可以简化这一点,它首先支持使用Promise#reduce
的这种形式的迭代,但我不想添加另一个库。
上面的代码将按顺序运行,如果你想检查它何时完成——它本身会返回一个promise。所以您可以执行onGetSubwebsSuccess(...).then(function(){ /* done here */ });
由于Web属性(Web.AllProperties)可以使用单个查询请求,使用以下语法:
clientContext.load(webs,'Include(Url,AllProperties)');
不需要使用CCD_ 4方法执行任何后续异步请求来加载每个web的web属性。
以下示例演示了如何从子站点加载web属性并将其保存到websProps
数组中:
(function(){
var ctx = SP.ClientContext.get_current();
var webs = ctx.get_web().get_webs();
var websProps = {};
ctx.load(webs,'Include(Url,AllProperties)'); //Note: Explicitly specify which properties to load for Web
ctx.executeQueryAsync(function(){
var e = webs.getEnumerator();
while (e.moveNext()) {
var web = e.get_current();
var webUrl = web.get_url();
var props = web.get_allProperties();
var propNameValues = props.get_fieldValues();
//save properties
//Note: For demonstration purposes vti_defaultlanguage property is saved, change it to your property name
websProps[webUrl] = {'DefaultLanguage': propNameValues['vti_defaultlanguage']};
}
console.log(JSON.stringify(websProps));
},
function(sender, args){
//Handle error
}
);
})();
相关文章:
- 没有找到相关文章