像JavaScript中的类似功能一样“等待”?

时间:2018-04-05 08:02:03

标签: javascript jquery

我正在使用等待sync的功能,之后它将加载内容。下面的函数在Firefox中完美运行但在IE11中不起作用

//Working in other browser and inserting the multiple records but not in IE

async function setup()
{
    await Word.run(async(context)=> {

        for (var i=0; i < 5; i++)
        {
            var controler = context.document.contentControls.getByTag("myTag"+i);
            controler.load();
            await context.sync();
            controler.items[0].insertPargraph("Adding paragraph "+i);
        }
    }
    )};

}

对于IE11,以下功能可以完美地插入一条记录

//Working in IE for the only one record
function setUp()
{
    Word.run(function (context){

        var selectedTag = context.document.contentControls.getByTag("myTag");
        context.load(selectedTag,'text');
        return context.sync().then(function()
        {
            controler.items[0].insertPargraph("Adding paragraph 0")
        });

    })
}

现在问题是我想迭代循环中的内容,我已经在forloop中写了返回函数,说明它不能正常工作

//Below function is not working
function setUp()
{
    Word.run(function (context){

        for (var i=0; i < 5; i++)
        {
            var selectedTag = context.document.contentControls.getByTag("myTag");
            context.load(selectedTag,'text');
            return context.sync().then(function()
            {
                controler.items[0].insertPargraph("Adding paragraph 0")
            });
        }
    })
}

如何为IE11浏览器编写await函数。我尝试了goto Lable功能,但也没有用。

2 个答案:

答案 0 :(得分:2)

您的async版本使用igetTag以及添加段落时,但后续代码示例没有。这对解决方案很重要。

共同点

您可以创建一个类似于my answer here的承诺链,但不同的可能很难将其应用于您的案例。基本上,您从已解决的承诺(p)开始,然后使用p = p.then(...)来构建链。

如果您不需要使用i的值

...那么你可以这样做:

function setUp()
{
    Word.run(function (context){
        var p = Promise.resolve();
        for (var i = 0; i < 5; i++)
        {
            p = p.then(function() {
                var selectedTag = context.document.contentControls.getByTag("myTag");
                context.load(selectedTag,'text');
                return context.sync().then(function()
                {
                    controler.items[0].insertPargraph("Adding paragraph 0")
                });
            });
        }
    })
}

如果确实需要使用i的值

...然后我们需要将它烘焙到代码中,因为你必须使用var(IE11有let,但它没有for循环的ES2015语义:

function setUp()
{
    Word.run(function (context){
        function doOne(index) {
            // We use `index` below
            var selectedTag = context.document.contentControls.getByTag("myTag" + index);
            context.load(selectedTag,'text');
            return context.sync().then(function()
            {
                controler.items[0].insertPargraph("Adding paragraph " + index)
            });
        }
        var p = Promise.resolve();
        for (var i = 0; i < 5; i++)
        {
            p = p.then(doOne.bind(null, i));
        }
    })
}

setUp一个返回值

您的async版本假定Word.run返回一个承诺,并且它希望其回调返回一个承诺。我找不到任何支持它的文档,但是,这些东西的网络文档看起来确实非常糟糕。

如果这两个假设都属实,那么要setUp返回一个承诺,我们只需要进行一些小改动:return Word.run之前在回调结束时和return p;(请参阅***条评论);

function setUp()
{
    return Word.run(function (context){                      // ***
        function doOne(index) {
            // We use `index` below
            var selectedTag = context.document.contentControls.getByTag("myTag" + index);
            context.load(selectedTag,'text');
            return context.sync().then(function()
            {
                controler.items[0].insertPargraph("Adding paragraph " + index)
            });
        }
        var p = Promise.resolve();
        for (var i = 0; i < 5; i++)
        {
            p = p.then(doOne.bind(null, i));
        }
        return p;                                            // ***
    })
}

但是如果Word.run没有返回一个承诺,或者没有预期来自其回调的承诺,那将无效,我们必须自己创建:

function setUp()
{
    return new Promise(function(resolve, reject) {           // ***
        Word.run(function (context) {
            function doOne(index) {
                // We use `index` below
                var selectedTag = context.document.contentControls.getByTag("myTag" + index);
                context.load(selectedTag,'text');
                return context.sync().then(function()
                {
                    controler.items[0].insertPargraph("Adding paragraph " + index)
                });
            }
            var p = Promise.resolve();
            for (var i = 0; i < 5; i++)
            {
                p = p.then(doOne.bind(null, i));
            }
            p.then(resolve).catch(reject);                   // ***
        })
    });
}

答案 1 :(得分:2)

我认为您要实现的目标是将sync()个调用链接在一起,以便Word.run中的回调仅在所有内容同步时解析。您可以使用Promise.all()执行此操作,以便在所有提供的承诺都已解决时生成承诺解析。

function setUp() {
  Word.run(function(context) {
    const promises = [];
    for (var i = 0; i < 5; i++) {
      var selectedTag = context.document.contentControls.getByTag("myTag");
      context.load(selectedTag, 'text');
      let p = context.sync().then(function() {
        controler.items[0].insertPargraph("Adding paragraph 0")
      });
      promises.push(p);
    }
    return Promise.all(promises);
  })
}