【发布时间】:2018-12-23 16:21:29
【问题描述】:
也许我困了,但是在什么情况下会出现以下情况?
let foo;
page
.evaluate(() => {
// return works... but not closure assignment
// doesn't work
foo = 'foo';
// works
return 'bar';
})
.then(bar => {
console.log('foobar', foo, bar);
// > foobar undefined bar
});
这发生在使用 puppeteer 的 mocha 测试中
更新:完整的代码
节点 9.11.2
/* global describe, it, before, after */
const fs = require('fs-extra');
const path = require('path');
const assert = require('assert');
const puppeteer = require('puppeteer');
const sleep = require('shleep');
const extPath = path.resolve(__dirname, '..', 'build');
const { name } = fs.readJSONSync(path.resolve(extPath, 'manifest.json'));
// Access chrome object in Extensions
// https://github.com/GoogleChrome/puppeteer/issues/2878
describe('chrome extension', () => {
let browser;
let extensionPage;
before(async function() {
this.timeout(90 * 1000);
// start puppeteer
browser = await puppeteer.launch({
headless: false,
args: [
`--disable-extensions-except=${extPath}`,
`--load-extension=${extPath}`
]
});
// poll instead of hope this is enough time?
const EXT_LOAD_DELAY = 100;
await sleep(EXT_LOAD_DELAY);
const targets = await browser.targets();
const extensionTarget = targets.find(
({ _targetInfo }) =>
_targetInfo.type === 'background_page' && _targetInfo.title === name
);
const page = await extensionTarget.page();
let foo;
page
.evaluate(() => {
// return works... but not closure assignment
// doesn't work
foo = 'foo';
// doesn't log
console.log('foo', foo);
// works
return 'bar';
})
.then(bar => {
console.log('foobar', foo, bar);
// > foobar undefined bar
});
});
it('should load', async () => {
assert(true);
});
});
测试截图
【问题讨论】:
-
如果
evaluate的回调在then的回调被调用之前被调用,上面的方法肯定会起作用。您是否检查过以确保evaluate的合同规定会发生这种情况?编辑:Looks to me like it does。上面的代码肯定会分配给顶部声明的foo。您遇到问题的真实代码必须不同(例如,您是否在页面函数中声明了foo?)。 -
由于您没有使用
async函数,因此async-await 标记无关紧要。 -
page.evaluate是否在不同的上下文中运行代码?就像在单独的浏览器中一样,具有完全不同的变量? -
好吧,它可以在函数上调用
.toSource(),将字符串发送到浏览器,然后eval它。 -
...是的,这正是它的作用:github.com/GoogleChrome/puppeteer/blob/master/lib/…
标签: javascript promise async-await mocha.js puppeteer