1

I am trying to run nightmare in a while loop. My problem is that the while loop is not waiting for nightmare to finish. That's my example code:

var Nightmare = require('nightmare');
var Screenshot = require('nightmare-screenshot');
var i = 0;

while(i < 10) {

    var nightmare = new Nightmare();
    nightmare.goto('https:/website/?id='+  i);
    nightmare.screenshot('/home/linaro/cointellect_bot/screenshot1.png');
    nightmare.use(Screenshot.screenshotSelector('screenshot' + i + '.png', 'img[id="test"]'));
    nightmare.run();
}

Is it possible to let the loop wait until nightmare has finished it's function queue? What other options do I have?

4

2 回答 2

2

使用函数而不是循环:

var nightmare;
var Nightmare = require('nightmare');
var Screenshot = require('nightmare-screenshot');

var runNext = function (i) {
    if (i < 10) {
        nightmare = new Nightmare();
        nightmare.goto('https:/website/?id='+  i);
        nightmare.screenshot('/home/linaro/cointellect_bot/screenshot1.png');
        nightmare.use(Screenshot.screenshotSelector('screenshot' + i + '.png', 'img[id="test"]'));
        nightmare.run(function () {runNext(i+1);});        
    }
}
runNext(0);

nightmare.run根据此文档接受回调:https ://github.com/segmentio/nightmare#runcb

一旦噩梦完成或出错,作为参数传递的函数就会被调用。

这通常是 nodejs 中大多数异步事物的工作方式。

于 2015-02-17T18:20:57.137 回答
1

虽然您需要提取一个函数,但最好不要只传递一个数字,而是传递完整的上下文。因此,您的功能看起来像

var screenshotPage = function(data){
  var nightmare = new Nightmare();
  nightmare.goto(data.url);
  nightmare.use(Screenshot.screenshotSelector(data.filePath, data.selector));
  nightmare.run();
}

您应该能够像这样运行示例

var Nightmare = require('nightmare');
var Screenshot = require('nightmare-screenshot');
var async = require('async')

var pages = [];

// You could do this recursively if you want
for(var i=0; i < 10; i++) {
    pages.push({
        url: 'https://website/?id='+ i,
        filePath: 'screenshot' + i + '.png',
        selector: 'img[id="test"]'
    });
}

var screenshotPage = function(data, callback){
  var nightmare = new Nightmare();
  nightmare.goto(data.url);
  nightmare.use(Screenshot.screenshotSelector(data.filePath, data.selector));
  nightmare.run(function(){
    callback(null);
  });
}

async.map(pages, screenshotPage, function(){
  // Here all screenshotPage functions will have been called 
  // there has been an error
});
于 2015-02-17T19:08:33.527 回答