简体   繁体   中英

Is there any way to break out of a function by running another function in JS

I am working on a simple project and I would like to create a simple helper function that checks for a error in a callback. If there is a error then it should break the whole function that called it. Code example:

//Makes call to database and tries to insert element

    db.collection("data").insertOne(
        {
            key: 'some-data'
        }, (error, result) => {
          //Return error if something goes wrong - else error is empty
          checkError(error, "Unable to load database");
          console.log("Succes item added")
        }
    ); 

Note: Yes this is node.js but this whole principle could be repeated in js with other callbacks - very simple repeatable error principle.

So in the insertOne function the first argument is some data I am adding to the database. The second argument is the callback function that is called after this async operation is finished. It returns a error which I could just handle by adding this if statement to the callback:

if (error) {
    console.error(error);
    return;
}

Buuut thats disrespecting the dry principle (bc I write the exact same if statement everywhere with no syntax being changed except the message) and is also distracting when reading the callback function. Now my issue is in the function checkError() even tho I can just print the error with the message or throw the error, I dont actually have a way to break the original callback so that it doesnt cause any more havoc in my database. I will go on to promisify this callback which is a solution. BUT I want to know if there is a way to this in the way I presented it here. Note: I dont want to use the try catch block bc thats replacing a if statement with another two blocks. My checkError function:

const checkError = function (error, msg = "Something went wrong") {
  if (error) console.error(`${msg}: error`);
  //Break original block somehow  ¯\_(ツ)_/¯
};

If I were to compress my question it would be: how to break a function with another function. Is there any way to achieve this?

I don't think this is possible. But you could achieve something similar with this:

function checkError (error, msg = "Something went wrong") {
    if (!error) return false;
    console.error(`${msg}: error`);
    return true;
};

db.collection("data").insertOne(
    {
        key: 'some-data'
    }, (error, result) => {
      //Return error if something goes wrong - else error is empty
      if (checkError(error, "Unable to load database")) return;
      console.log("Succes item added")
    }
); 

Things become easier when you use promises.

Often asynchronous APIs provide a promise interface, and this is also the case for mongodb/mongoose, where you can chain a .exec() call to execute the database query and get a promise in return. This gives you access to the power of JavaScript's async / await syntax. So you can then do like this:

async function main() {
    // Connect to database
    //     ...
    // Other db transactions
    //     ...
    let result = await db.collection("data").insertOne({ key: 'some-data'}).exec();
    console.log("Item added successfully");
    // Any other database actions can follow here using the same pattern
    //     ...
}

main().catch(err => {
    console.log(err);
});

The idea here is that await will throw an exception if the promise returned by .exec() eventually rejects. You can either put a standard try...catch construct around it to deal with that error, or you can just let it happen. In the latter case the promise returned by the wrapping async function will reject. So you can deal with the error at a higher level (like done above).

This way of working also removes the need for numerous nested callbacks. Often you can keep the nesting to just one of two levels by using promises.

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