2016-03-25 10 views
2

ビューポートサイズのタイルをキャプチャして完全なWebページのスクリーンショットを撮りたい。それはほとんど終わりましたが、私は約束が新しく、正しいやり方を模索しています。webdriver.ioのwhileループで約束をまとめる

ここに私のコードです。問題は、client.execute(...)への呼び出しです。それから、(...)はループの繰り返しの間にそれ自身を待たない。最後の「終わり」は前の「当時」を待っているわけではないので、それがコメントアウトされています。

... 
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() 
    ; 

この場合、約束を使用する正しい方法は何ですか?

ありがとうございました。

答えて

5

whileループは即座に実行されるが、各非同期実行後にループを決定する必要があるため、whileルックを使用して不確定な非同期操作をチェーンすることはできません。

代わりに、あなたは約束を返す内部関数next()を作成することができますし、行われ、前.then()ハンドラ内またはそれを返すことによってかどうかチェーンにループ内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()リターンを約束するので、あなたは1つのシーケンシャルチェーンに一緒にすべてのあなたのスクリーンショット.then()ハンドラとその意志チェーン内からreturn next();を繰り返し呼び出すことができますし、それはチェーンを終了させる。

関連する問題