简体   繁体   中英

Is it possible to create a custom mongoose querying function?

I am coding a server using Node.js and ExpressJS. My database is MongoDB for which I use MongooseJS as the middleware.

The server has many endpoints and almost every one of them has the same code at the beginning - a query to the DB to retrieve devices that have been assigned to chosen room. Simplified, repeating code is below:

Room
        .findOne({ _id: roomId })
        .populate({
            path: "deviceGroups",
            populate: {
                path: "devices"
            }
        })
        .exec(() => {
            Device.findOne({ _id: deviceId }).exec((err, device) => {
                if (err) {
                    res.send(err);
                } else {
                    // do anything you need with the results here
                }
            });
        });

I know that the queries are asynchronous, so if I want to do anything with the query's results I have to do it in the query's callback function. Also, while extracting the query to an external function I guess there is no way to pass express' res object, right? It would be needed to handle potential errors during the queries.

My question is: considering the above information about asynchronysm, is it possible to create some custom function like the one below, that will be retrieving ie the devices? The function's invocation's result could be assigned to some variable. I guess if it is at all possible, it should be wrapped with some JS's promise handlers, right?

What I want to achieve is to reduce amount of repeating code.

Prototype function:

const getDevice = (roomId, deviceId) => {
    Room
        .findOne({ _id: roomId })
        .populate({
            path: "deviceGroups",
            populate: {
                path: "devices"
            }
        })
        .exec(() => {
            Device.findOne({ _id: deviceId }).exec((err, device) => {
                return device;
            });
        });
};

You can create a promise if Room.exec doesn't already return something that has a then and catch

function getDivice(roomId){
  return new Promise(
    (resolve,reject)=>
      Room
      .findOne({ _id: roomId })
      .populate({
          path: "deviceGroups",
          populate: {
              path: "devices"
          }
      })
      .exec(() => {
          Device.findOne({ _id: deviceId }).exec((err, device) => {
              if (err) {
                  reject(err);
              } else {
                resolve(device);
                  // do anything you need with the results here
              }
          });
      })
  );
}

//call it like this:
getDivice(someid)
.then(
  divice=>{
    //do something with divice
  }
)
.catch(
  err=>{
    //do something with the error
  }
)

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