ClericPy / ichrome

Chrome controller for Humans, based on Chrome Devtools Protocol(CDP) and python3.7+.
https://pypi.org/project/ichrome/
MIT License
227 stars 29 forks source link

怎么获取promise的结果 #100

Closed zenghh closed 1 year ago

zenghh commented 2 years ago
function f(wsConnId, countryId) {
        return new Promise((resolve, reject) => {
            try {
                window.readit.conId = wsConnId;
                ns_gen5_net.url = "/zap";
                const counter = window.readit.WebsocketTransportMethod.Counter++;
                window.addEventListener("xcft" + counter, function(event) {
                    window.readit.conId = "";
                    ns_gen5_net.url = "";
                    resolve(event.detail);
                });
                window.dispatchEvent(new CustomEvent("xcftr", {detail: counter}));
            } catch(e) {
                reject(e);
            }
        });
    }

比如上面这段代码,我要怎么获取结果,谢谢

ClericPy commented 2 years ago

你是在 ichrome 里面注入的 JS 吗, 目前那个方式只能同步代码然后在代码最后一行放上变量名字, 就会输出到返回值里了, 和你在 dev tools 的控制台一模一样

如果是异步结果的话, 我记得预留了一个等待 console 数据的函数, await tab.wait_console_value() 就行了, 因为我也遇到过类似场景, 要做的就是在 JS 里通过 console.log 打印到控制台

zenghh commented 2 years ago

用 tab.js 能行吗

ClericPy commented 2 years ago

tab.js 是注入 JS, 类似于浏览器 F12 dev tools 的控制台上运行, 拿到的结果也是那个控制台上的结果, 是同步模型

如果是异步函数(不是马上返回结果的), 可以让函数里面把结果打印到 console, 然后 wait console 的信息就好了

zenghh commented 2 years ago

好的,谢谢,这个promise等待的应该很多人会有需求,能加个吗

ClericPy commented 2 years ago

这个是 cdp 里默认带的么, 其实你只要在函数里把返回值提前 console.log 打印出来然后 wait console 就好了啊, 不需要新函数支援, 现有函数足够了, 也就一行代码

甚至也可以用现有的其他方式, 比如函数结束时在 DOM 里加入一个新的 node 放结果, 然后 Python 里面 wait tag 也可以

尽量把复杂的逻辑放在 JS, JS 才是一等公民

zenghh commented 2 years ago

谢谢,我试看看

ClericPy commented 2 years ago

嗯, 有问题随时来问, 不过我估计下班时间才能回复

最近新功能的添加有些麻烦, 因为身体原因精力不太够, 而且下一个迭代主要方向还是 ichrome 集群部署时候的 HTTP web 化, 这个模块旧的代码太难用了, 打算重构一份

zenghh commented 2 years ago

https://github.com/cyrus-and/chrome-remote-interface/issues/222

像这样,它这个 awaitPromise是cdp支持的吗

let js =  `
                new Promise((fulfill, reject) => {
                    setTimeout(() => {
                        fulfill('your result');
                    }, 1000); // simulate a long-running async operation
                })`;
            const result = await Runtime.evaluate({
                expression: js, //Just testing a simple promise at this point
                awaitPromise: true
            }); //Throws message: 'Result of the evaluation is not a promise'
ClericPy commented 2 years ago

https://chromedevtools.github.io/devtools-protocol/tot/Runtime/#method-evaluate

这是原生支持的参数啊, 在我那个 await tab.js(js_code, kwargs={"awaitPromise":True}) 应该是可以的

https://github.com/ClericPy/ichrome/blob/master/ichrome/async_utils.py#L1444

    result = await self.send("Runtime.evaluate",
                             timeout=timeout,
                             expression=javascript,
                             kwargs=kwargs)

我底层同样使用的这个 cdp 协议的

zenghh commented 2 years ago

好的,谢谢