Open reflectiz opened 8 years ago
Thank you for your pull-request.
Can you describe a use-case where this nodeCallback
is necessary and cannot be solved in other ways?
Hi jhnns
I've added this functionally because I needed to initiate an action base options for events triggered at the phantomjs client side code. I'm using MutationObserver to monitor changes on the page, and when change occurs, the nodeJS server need to react. I haven't found any other option in phridge current code.
Thanks Ysrael
You're right. There is currently no way to achieve this.
However, there are some problems with your implementation. What happens if I have multiple instances of Page
and I would like to install event listeners individually. We somehow need to have a record so that we now where "to call back".
For instance, we could have a third argument emit
:
phantom.run(function (resolve, reject, emit) {
setInterval(() => {
emit("hi");
}, 100);
resolve();
});
somePage.run(function (resolve, reject, emit) {
setInterval(() => {
emit("hi");
}, 100);
});
phantom.on("hi", function () { ... });
somePage.on("hi", function () { ... });
This way...
nodeCallback
variable in the upper scopeHowever, there might be another problem: When we're inside PhantomJS, we are not inside the actual page context. When using the evaluate
function provided by PhantomJS, we're not allowed to access the scope either. Hence, this code will not work:
page.run(function (resolve, reject, emit) {
this.evaluate(function () {
// emit is not defined because we're in the actual page context now
emit("hi");
});
resolve();
});
We would need to use the onCallback
mechanism as described here:
page.run(function (resolve, reject, emit) {
this.onCallback(function (message) {
emit(message);
});
this.evaluate(function () {
window.callPhantom('hi');
});
resolve();
});
This is very ugly – and again, we have the same problem that we need to collate callbacks from different sources...
I totally see the use-case and I wish, phridge would provide an easy API for this. But a proper implementation takes a lot of effort...
For instance, it would be cool to have a evaluate
method on our page instance that mitigates all the cruft around it. This is probably what you would like to use:
page.evaluate(function (resolve, reject, emit) {
var observer = new MutationObserver(function(mutations) {
mutations.forEach(function(mutation) {
emit("mutation", mutation.type);
});
});
observer.observe(document.body, {
attributes: true,
childList: true,
characterData: true
});
});
page.on("mutation", function (mutationType) {
});
I want to be able to call from the phantom code to the node module. The code added a function calls "nodeCallback" at the phantom side and property calls "onCallback" on the "page" object.