如何使webEnumerator.moveNext等到executeQueryAsync查询执行 [英] How to make webEnumerator.moveNext wait until executeQueryAsync query executes

查看:377
本文介绍了如何使webEnumerator.moveNext等到executeQueryAsync查询执行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在将控制权交还给webEnumerator.moveNext之前完成executeQueryAsync吗?

I want executeQueryAsync to complete before giving back control to webEnumerator.moveNext, anyway ?

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"的警报,

What's happening now is, I get alert for "Loop 1" twice and then alert for "Loop 2" when it should be like this,

Loop 1
Loop 2
Loop 1
Loop 2

推荐答案

JavaScript I/O通常是非阻塞的.

JavaScript I/O is usually non blocking.

context.executeQueryAsync立即返回,因此它继续迭代原始循环.完成后,它将接受回调.

context.executeQueryAsync returns immediately, so it keeps iterating the original loop. It accepts a callback for when it's done.

您想要的是对其进行同步.允诺的一个概念就是承诺.既然您已经用jQuery标记了它,则可以使用它的实现(或者更好的是像Bluebird promises这样的强大实现)并执行以下操作:

What you want is to synchronize it. One concept that allows that is Promises. Since you already tagged this with jQuery, you can use its implementation (or better, a strong one like Bluebird promises) and do something like:

// 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支持这种形式的迭代,但是我不想添加其他库.

This can get a lot simpler using a stronger promise library like Bluebird which supports this form of iteration using Promise#reduce in the first place, but I didn't want to add another library.

如果您想检查完成时间,上面的代码将按顺序运行-它本身返回一个promise.所以你可以做onGetSubwebsSuccess(...).then(function(){ /* done here */ });

The code above will run in sequence, if you want to check when it's done - it returns a promise itself. So you can do onGetSubwebsSuccess(...).then(function(){ /* done here */ });

这篇关于如何使webEnumerator.moveNext等到executeQueryAsync查询执行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆