简体   繁体   中英

Node.js callback

I can't seem to grasp the concept of a callback. I haven't worked with them before so bear with me. To get my hands wet, I'm trying to login to twitter with zombie.js.

Here is an example:

var Browser = require("zombie");
var browser = new Browser({ debug: true})

browser.visit("https://mobile.twitter.com/session/new", function (callback) {
    browser.fill("username", "xxxxx");
    browser.fill("password", "xxxxx");
    browser.pressButton("Sign in", function (err, success) {
        if(err){
            console.log(browser.text('.message'));
            console.log('There has been a error: ' + err);
        }
        else{
            console.log('Worked!');
        }

    });
});

At the browser.pressButton part, it will determine if I have been able to successfully login or not, depending on if .message contains the text "Typing on your phone stinks, we know! Double-check your username and password and try again."

However, I don't understand how it determines to fire the callback err . If .message isn't present in the html, then I would like to trigger the success callback to move onto the next function.

The convention Zombie seems to use for callbacks comes from node.js where the first argument is an error object, which should be null on success, and any subsequent arguments are for the success case. If you define a callback, the library you are using (Zombie in this case) will execute your callback function when their async operation is complete. When your callback is invoked it means "OK, an operation has completed and you can now process the result as you see fit". Your code needs to look at that first argument to decide if the operation was a success or failure.

When you accept a callback function as an argument and then perform some (possibly asynchronous) operation, the callback is the way for you to tell the calling library you are done, and again use that first argument to distinguish errors from success.

Part of your confusion is probably coming from the fact that your function signature for the callback to browser.visit is wrong. You need to name that first argument to clearly indicate it's an error like this:

browser.visit("https://mobile.twitter.com/session/new", function (error, browser) {

So in the body of that anonymous callback function, if zombie couldn't load that page, the error argument will have info about the error. If the page did load correctly, error will be null and the browser 2nd argument can be used to further tell zombie to do more stuff on the page. This is how Zombie says "I'm done with the visit operation, time for you to handle the results."

visit doesn't pass a callback argument, the anonymous function you pass as an argument to visit IS THE CALLBACK . You could code it like this to clarify (although nobody does)

browser.visit("https://mobile.twitter.com/session/new", function callback(error, browser) {

So that's a callback when a library needs to tell you it is done. You don't invoke it. The library invokes it and you put code inside it.

On the other hand, when your code does async operations, you need to invoke the callback that you received as a function argument appropriately to tell your caller that you are done and whether it was success for failure. In this case, you don't do any of your own async code, so there's no need for you to invoke any callback functions.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM