for循环不等待函数结束

时间:2013-09-09 14:56:16

标签: microsoft-metro winjs

我在页面上有5个链接,我必须检查所有链接是否正常工作。这是代码

 // iterate through each link and check if ti works.
 for(var i=0; i < 5; i++) {
    var ifLinkWorks = verifyLinkWorks(links[i]);
    if(ifLinkWorks){  OK  }
    else{ error }
 }

这是verifyLinkWorks功能。它打开一个链接。打开后,它会检查页面是否正确加载

        function verifyLinkWorks(link) {
          return winjs.Promise(function(complete) {          
          link.click();  
          // wait for page to load
          return winjs.promise.timeout(4000).then(function () {
            // check if page is loaded
            var islinkOK = IsPageLoaded();
            complete(islinkOK); // i want verifyLinkWorks to return this value
            });
         });
    }

到达link.click()后,它不会等待页面加载。相反,它跳转到外部for循环中的if condtion(这使得linkWorks = undefined因此,给出Error)。如何让它在verfifyLinkWorks函数中等待。 提前谢谢......

2 个答案:

答案 0 :(得分:1)

您需要等待每个承诺的结果,一次全部或单独。由于动作本质上都是异步的,代码不能等待,但它可以在完成所有工作时调用函数。

在这里,我创建了一个数组,用于保存每个Promise实例。循环完成后,代码等待所有内容完成,然后使用传递的数组,检查每个索引的结果。

// iterate through each link and check if it works.
var verifyPromises = [];
for(var i=0; i < 5; i++) {
   verifyPromises.push(verifyLinkWorks(links[i]));
}

WinJS.Promise.join(verifyPromise).done(function(results) {
    for(var i=0; i < 5; i++) {
        var ifLinkWorks = results[i];
        if (ifLinkWorks) {  /* OK */  }
        else { /* error */ }
    }
});

如果link.click()调用失败,我会将其封装在try / catch块中:

function verifyLinkWorks(link) {
     return WinJS.Promise(function(complete, error) {          
          try {
              link.click();  
          } catch (e) {
              complete(false);  // or call the error callback ...
          }
          // wait for page to load, just wait .. no need to return anything
          WinJS.Promise.timeout(4000).then(function () {
              // check if page is loaded
              var islinkOK = IsPageLoaded();
              // finally, call the outer promise callback, complete
              complete(islinkOK); 
          });
     });
}

如果您想检查网址的有效性,建议您考虑使用WinJS.xhr方法代替执行HEAD请求(rfc)。使用每个link变量,您可以使用timeout验证网址上是否有合理的响应,而无需下载整页(或切换到GET并检查响应正文)

WinJS.Promise.timeout(4000, 
    WinJS.xhr({
        type: 'HEAD',
        url: link
    }).then(function complete(result) {
        var headers = result.getAllResponseHeaders();

    }, function error(err) {
        if (err['name'] === 'Canceled') {

        }
        if (err.statusText) {

        }
    })
);  

答案 1 :(得分:0)

好的,这是win js promise对象的msdn代码示例的链接。

Promise winjs

现在通过代码

<button id="start">StartAsync</button>
<div id="result" style="background-color: blue"></div>

<script type="text/javascript">

WinJS.Application.onready = function (ev) {
    document.getElementById("start").addEventListener("click", onClicked, false);
};

function onClicked() {
    addAsync(3, 4).then(
        function complete(res) {
             document.getElementById("result").textContent = "Complete";
        },
         function error(res) {
             document.getElementById("result").textContent = "Error";
        },
         function progress(res) {
             document.getElementById("result").textContent = "Progress";
      })

 }
function addAsync(l, r) {
     return new WinJS.Promise(function (comp, err, prog) {
        setTimeout(function () {
            try {
                var sum = l + r;
                 var i;
                 for (i = 1; i < 100; i++) {
                     prog(i);
                }
                     comp(sum);
                }
                catch (e) {
                    err(e);
                }
            }, 1000);
        });
    }
</script>

您将看到 addAsync(3,4).then()功能。因此,所有代码都将保留在该函数内,以便具有延迟响应。抱歉我使用标签,因此无法正确编写。

同时浏览链接then for winjs promise