Javascript 在webdriver.io的while循环中链接承诺

Javascript 在webdriver.io的while循环中链接承诺,javascript,selenium,promise,es6-promise,webdriver-io,Javascript,Selenium,Promise,Es6 Promise,Webdriver Io,我想通过捕获视口大小的分幅来截取完整网页的屏幕截图。差不多完成了,但我对承诺还很陌生,我正在寻找正确的方法 这是我的密码。问题是对客户端的调用。执行…然后。。。在循环迭代之间不等待自身。最后的“结束”并不等待前一个“然后”,这就是为什么它被注释掉了 ... var client = webdriverio.remote(options); ... client ... .then(function() { var yTile = 0; var heightCap

我想通过捕获视口大小的分幅来截取完整网页的屏幕截图。差不多完成了,但我对承诺还很陌生,我正在寻找正确的方法

这是我的密码。问题是对客户端的调用。执行…然后。。。在循环迭代之间不等待自身。最后的“结束”并不等待前一个“然后”,这就是为什么它被注释掉了

...
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 look来链接数量不确定的异步操作,因为while循环将立即运行到完成,但您需要在每次异步执行后做出循环决策

相反,您可以创建一个内部函数next,该函数返回一个承诺并重复调用它,将每个函数链接到上一个函数,直到完成,并在循环中决定是否通过在上一个函数中返回另一个函数来链接到下一个函数。然后,处理程序或您可以通过只返回常规值而不是承诺来结束该链

...
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返回一个承诺,您可以重复调用return next;在.then处理程序中,将所有屏幕截图链接到一个连续的链中,直到您最终返回一个值,而不是一个承诺,这将结束该链