在承诺链中等待DOM元素中的突变

我在Node.js中制作了一些网页抓取工具,用PhantomJS拍摄了一个网站上出现的地图。

但是,页面打开后,会在地图所在的位置显示加载消息。 地图准备就绪后,消息消失( visibility: hidden ),并显示地图。

正因为如此,我不能调用page.render()直到hidden #loader (或者我会得到一个加载消息的图片,而不是很酷)。

 // ... Open the page .then(function(content) { return page.evaluate(function() { // Wait for #loading to get hidden somehow ... var clipRect = document.getElementById('map').getBoundingClientRect(); return { top: clipRect.top, left: clipRect.left, width: clipRect.width, height: clipRect.height }; }); }) // Render and process the picture ... 

我考虑使用突变观察者 ,但无法find使用它的方法,因为我处于承诺链中 ,并且事件侦听器不能按我的要求工作。

我也经常检查visibility属性,直到它被隐藏,正如这里所解释的,但PhantomJS通过Node的控制台报告:

 TypeError: null is not an object (evaluating 'child.transform') 

另外,如果可能的话,我想避免这种解决方法,因为它们非常耗费CPU资源。

任何想法如何等待#loader在这些情况下hidden

我终于解决了这个问题,感谢phantomjs-node的mantainer, amir20 ,所以都归功于他。 正如他在这个问题上解释的:

waitFor期望返回一个值。 但evaluate返回一个Promise 。 所以这就是为什么它不工作。 这不是模块的问题,而是waitFor问题。 由于一切都是asynchronous执行的,所以你必须等待这个值。

有问题的function(由他创build)如下:

 function waitUntil(asyncTest) { return new Promise(function(resolve, reject) { function wait() { asyncTest().then(function(value) { if (value === true) { resolve(); } else { setTimeout(wait, 100); } }).catch(function(e) { console.log('Error found. Rejecting.', e); reject(); }); } wait(); }); } 

因此,适用于我的具体示例,应该这样使用:

 waitUtil(function() { return sitepage.evaluate(function() { return document.querySelectorAll('#loader').style.visibility == "hidden"; }) }).then(function(){ // #loading is now hidden return page.evaluate(function() { var clipRect = document.getElementById('map').getBoundingClientRect(); return { top: clipRect.top, left: clipRect.left, width: clipRect.width, height: clipRect.height }; }); }) // Render and process the picture ...