NightmareJS screenshot callback

2019-07-16 14:37发布

问题:

I'm using this framework to make screenshots of several urls. The process of taking the screenshot is async, and the method does not provide a way to execute a callback, and I want to execute a callback when each screenshot is made on this script:

nightmare = new Nightmare();
urls.forEach(function (url) {
    nightmare.goto(url).screenshot(path);
});

nightmare.run(function () {
  console.log('finished all');
});

Any ideas how can I do this?

回答1:

I found a way to do this, with the "use" method for executing plugins.

nightmare = new Nightmare();
urls.forEach(function (url) {
    nightmare.goto(url).screenshot(path).use(function () {
        console.log('finished one');
    });
});

nightmare.run(function () {
    console.log('finished all');
});


回答2:

This appears to be the purpose of the run() method. You probably want to set up and run each screenshot within the loop, since the screenshot() method relies on the phandomjs method render(), and render() is strictly synchronous (at least as of a year ago):

urls.forEach(function (url) {
    nightmare = new Nightmare();
    nightmare.goto(url).screenshot(path).run(function(err, nightmare) {
        console.log('this executes when your screenshot completes');
        // run() appropriately tears down the nightmare instance
    });
});

console.log('finished all');

You don't gain any asynchronous benefits from setting up all the screenshots at once, and "finished all" is guaranteed to only run once all screenshots have been rendered.

Alternatively, in the nightmarejs source, it looks like screenshot() does take a second done parameter that appears to be a callback, but it passes it directly into the phantomjs render() method, and as seen in the above link there was some resistance to allowing that method to take a callback.