【问题标题】:puppeteer evaluate results in context destroyedpuppeteer 在上下文被破坏的情况下评估结果
【发布时间】:2018-09-23 04:03:41
【问题描述】:

尝试等待 DOM 突变停止但以 Execution context was destroyed. 结尾,欢迎提出任何建议

            page.evaluate(() => {

                return new Promise((resolve,reject) => {

                    var timerId;

                    function resetTimer() {
                        clearInterval(timerId);
                        timerId = setTimeout(() => {
                            resolve(true);
                        }, 3000)
                    }

                    new MutationObserver(
                        () => {
                            resetTimer();
                        }
                    ).observe(document.getElementById('root'), {
                        attributes: true, childList: true
                    });

                    resetTimer();

                })
            })
        })

协议错误(Runtime.callFunctionOn):执行上下文被破坏。未定义

  at Promise (node_modules/puppeteer/lib/Connection.js:198:56)
  at CDPSession.send (node_modules/puppeteer/lib/Connection.js:197:12)
  at ExecutionContext.evaluateHandle (node_modules/puppeteer/lib/ExecutionContext.js:71:75)
  at ExecutionContext.evaluate (node_modules/puppeteer/lib/ExecutionContext.js:46:31)
  at Frame.evaluate (node_modules/puppeteer/lib/FrameManager.js:299:20)

【问题讨论】:

    标签: node.js es6-promise jestjs puppeteer


    【解决方案1】:

    上面的 sn-p 是在页面上获得导航锁之前运行的。在导航之间运行page.evaluate 可能会引发此错误。

    从这里找到的,

    1. Error: Protocol error (Runtime.callFunctionOn): Execution context was destroyed.
    2. No page navigation lock ?

    修复是(至少在我的情况下)等到 URL 更改然后page.evaluate

    【讨论】:

    • 我添加了一个await page.waitForSelector('#my-selector'),它工作正常!好点。
    【解决方案2】:

    注意事项:

    • 您是否在代码中使用 async/await?如果你有一个承诺但不使用任何链或异步/等待,那么它应该会抛出这样的错误。
    • 另外,您也正在从观察者回调中触发 resetTimer。
    • 如果没有,那么您可能没有监控该 dom 元素的正确更改。

    这是一个简单的反应应用程序,它会在 2 秒后改变状态。

    class App extends Component {
      constructor() {
        super();
        this.state = { bar: "foo" };
      }
    
      componentDidMount() {
        setTimeout(() => this.setState({ bar: "not foo" }), 2000);
      }
    
      render() {
        return <div className="App">{this.state.bar}</div>;
      }
    }
    

    这是上面sn-p的修改代码。

     await page.evaluate(() => { // wait for it to resolve
        return new Promise((resolve, reject) => {
          var timerId;
    
          function resetTimer() {
            clearInterval(timerId);
            timerId = setTimeout(() => {
              resolve(true);
            }, 5000); // resolves after some time
          }
          const observer = new MutationObserver((mutations) => {
            // show me the changes
            mutations.forEach(function(mutation) {
                console.log(mutation.type);
            });
            // reset timer etc.
            resetTimer();
          });
    
          // observe a lot of changes
          observer.observe(document.getElementById("root"), {
            attributes: true,
            characterData: true,
            childList: true,
            subtree: true,
            attributeOldValue: true,
            characterDataOldValue: true
          });
        });
      });
    

    结果如下:

    【讨论】:

    • 感谢您的帮助,但修复方法是在 page.evaluate 之前在页面上获得导航锁定,在导航之间运行它会导致上述错误
    猜你喜欢
    • 1970-01-01
    • 2014-06-27
    • 2021-10-04
    • 2020-06-14
    • 2021-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多