简体   繁体   中英

Loopback : Making synchronous call to loopback api

I want to make a synchronous call to one of the APIs that i have designed using loopback. Here is my code :

router.get('/friends', function(req, res, Array) {
    var friendsList = []
    for(var counter=0;counter<length;counter++){
                  Model.findById(Array[counter].Id,function(err, record) {
                    if(record){
                        friendsList.push(record);
                    }
                  });
                }
                res.status(200).json(friendsList);
});

Now im getting the response before the array, friendList is getting populated completely. I want to make this synchronous and get the correct response. What should i do?

Thanks!

a simplistic way to do it is

  • set a variable to length
  • every time the callback is called, decrease this variable by 1
  • when it reaches zero, you've processed the final callback
  • WITHIN the callback, call res.status...

Like this:

router.get('/friends', function(req, res, array) {
    var friendsList = [];
    var remaining = length;
    for(var counter=0;counter<length;counter++){
        Model.findById(array[counter].Id, function(err, record) {
            if (record){
                friendsList.push(record);
            }
            remaining -= 1;
            if (remaining == 0) {
                res.status(200).json(friendsList);
            }
        });
    }
});

for completeness ... since you're using nodejs ... use (native) Promise and arrow function syntax

router.get('/friends', (req, res, array) =>
    Promise.all(array.map(item => 
        new Promise((resolve, reject) => 
            Model.findById(item.Id, (err, record) => 
                resolve(record || undefined)
            )
        )
    ))
    .then(friendsList => 
        res.status(200).json(friendsList.filter(item => 
            item !== undefined
        ))
    )
);

I'd use async and underscore modules

var async = require('async');
var _ = require('underscore');

router.get('/friends', function(req, res, Array) {
    var friendsList = [];
    var waterfallFunctions = [];
    _.each(Array, function(element) {
      waterfallFunctions.push( function(next) {
        Model.findById(element.Id,function(err, record) {
          if (err) return next(err);

          if(record){
            friendsList.push(record);
          }

          next();
        });
      });
    });

    //async waterfall calls the functions in the array in order.
    async.waterfall(waterfallFunctions, function (err) {
      if (err) return res.status(500);

      res.status(200).json(friendsList);
    });

});

Using Promises and the $in operator in Mongoose:

router.get('/friends', function(req, res, arr) {
    var promise = Model.find({ _id: { $in: arr.slice(0, length).map(function (e) { return e.Id }) } }).exec()
    promise.then(function (friendsList) {
        res.status(200).json(friendsList)
    })
})

arr.slice picks the first length elements from the array. Model.find creates a single query, which is more efficient than performing multiple findById queries. The $in operator accepts an array of ids to do a look-up against. .exec() creates a single promise, which is resolved with .then(...) .

You should wait until the N findById calls finish so a solution is make an array of promises and use the Promise.all method.

router.get('/friends', function(req, res, Array) {
    var friendsList = []
    var friendsPromises = []

    for (var counter=0; counter<length; counter++) {
        var friend = Model.findById(Array[counter].Id;
        friendsList.push(friend)

        friend.then(function(record) {
            if (record) {
                friendsList.push(record);
            }
        })
    }

    Promise.all(friendsPromises).then(function(){
        res.status(200).json(friendsList);    
    })
});

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