簡體   English   中英

在webdriver.io中的while循環中鏈接諾言

[英]Chaining promises in a while loop in webdriver.io

我想通過捕獲視口大小的圖塊來拍攝完整網頁的屏幕截圖。 它已經差不多完成了,但是我對諾言很陌生,我正在尋找正確的方法。

這是我的代碼。 問題是調用client.execute(...)。then(...)不會在循環迭代之間等待自身。 最后的“結尾”都不等待前面的“ then”,這就是為什么將其注釋掉的原因。

...
var client = webdriverio.remote(options);
...
client    
  ...
  .then(function() {

    var yTile = 0;
    var heightCaptured = 0;

    while(heightCaptured < documentSize.height) {
      var tileFile  = 'screenshot-' + yTile + '.png';

      client
      .execute(function(heightCaptured) {
        window.scrollTo(0, heightCaptured);
      }, heightCaptured)
      .then(function() {
        console.log('captured: ' + tileFile);
        client.saveScreenshot('./' + tileFile);

        return client;
      });

      heightCaptured += viewportSize.height;
      yTile++;
    }

  })
  //.client.end()
  ;

在這種情況下使用諾言的正確方法是什么?

謝謝。

您不能使用while外觀來鏈接不確定數量的異步操作,因為while循環將立即運行到完成,但是您需要在每次異步執行之后做出循環決策。

相反,您可以創建一個內部函數next() ,該函數返回一個promise並反復調用它,將其鏈接到前一個,直到完成為止,並在循環內確定是否將另一個調用鏈接到next()是將其返回到.then()處理程序,也可以通過返回常規值(而不是諾言)來結束鏈。

...
var client = webdriverio.remote(options);
...
client
    ...
    .then(function () {
        var yTile = 0;
        var heightCaptured = 0;

        function next() {
            if (heightCaptured < documentSize.height) {
                var tileFile = 'screenshot-' + yTile + '.png';

                // return promise to chain it automatically to prior promise
                return client.execute(function (heightCaptured) {
                    window.scrollTo(0, heightCaptured);
                }, heightCaptured).then(function () {
                    console.log('captured: ' + tileFile);

                    // increment state variables
                    heightCaptured += viewportSize.height;
                    yTile++;

                    // return this promise to so it is also chained properly
                    // when this is done, call next again in the .then() handler
                    return client.saveScreenshot('./' + tileFile).then(next);
                });

            } else {
                // Done now, end the promise chain by returning a final value
                // Might also consider returning yTile so the caller knows
                // how many screen shots were saved
                return client;
            }
        }
        // start the loop
        return next();
    }).then(function () {
        // done here
    }, function (err) {
        // error here
    });

作為參考,如果您位於.then()處理程序中,並且從.then()處理程序返回一個諾言,則該諾言將鏈接到先前的諾言。 如果您返回一個值,則承諾鏈到此結束,並且該值作為整個鏈的最終解析值返回。

因此,在此示例中,由於next()返回一個promise,因此您可以重復調用return next(); .then()處理程序內部,它將所有屏幕快照鏈接到一個順序鏈中,直到您最終僅返回一個值(而不是promise),並且該鏈結束。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM