简体   繁体   中英

Converting an asynchronous function to synchronous in node js?

I am working with an API which expects me to pass the first four digits of a card and it returns me the card country. Now, here is my problem. It turns out that the function that I am calling is asynchronous and when I try to return the country, it actually goes to the return value before even the async call is fully executed. I wanted the call to be synchronous which means I dont want the function to return me the default data and wait for the actual response from the API. This is what I tried so far. I actually used console.log() statement to figure out the whole problem.

module.exports = {
  bvncheck: function (cardnum) {
    console.log("cardnumber", cardnum);
    flutterwave.BIN.check(cardnum, function (req, res) {
      var country = res.body.data.country;
      console.log("country", country);
      return country;
    });
  }


};

app.post('/checkcardbin', function (req, res) {
  var cardnumber = req.body.cardnumber;

  //var r = fd.bvncheck(cardnumber);

  var r = fd.bvncheck(cardnumber);
  console.log("result", r);
});

I expected the following output in the following order-

1. cardnumber *****
2. country  *****
3. result ******

But in reality, it is returning me in the following order and due to the asynchronous nature, I am getting result to be undefined because the data is returned before the function is actually done executing.

1. cardnumber *****
2. result ******
3. country *****

How can I solve this issue? Any suggestions or advise is highly appreciated.

I had to change your module by including callback. So that fd.bvncheck will wait for the callback.

module.exports = {
        bvncheck: function (cardnum, callback) {
            console.log("cardnumber", cardnum);
            flutterwave.BIN.check(cardnum, function (req, res) {
                var country = res.body.data.country;
                console.log("country", country);
                callback(country);
            });
        }
    }
    app.post('/checkcardbin', function (req, res) {
        var cardnumber = req.body.cardnumber;

        //var r = fd.bvncheck(cardnumber);

        fd.bvncheck(cardnumber, function(r) {
            console.log("result", r);
        });

    });

You can use promise fro that

module.exports = {
  bvncheck: function(cardnum) {
    return new Promise(function(resolve, reject){
      flutterwave.BIN.check(cardnum, function(req,res){
        var country = res.body.data.country;
        resolve({country:country, cardnumber: cardnum});
      });
    });
}

app.post('/checkcardbin',function(req,res){
  var cardnumber = req.body.cardnumber;
  fd.bvncheck(cardnumber).then(function(v){
    console.log(v);
  });
});

The bvncheck function isn't written properly. It's async but it doesn't provide a way to pass in a callback. As it's currently written there's no way to access the returned country from outside the bvncheck function. That return country; line is doing nothing of any value. It should look more like this,

module.exports = {
  bvncheck: function(cardnum, callback) {
    console.log('cardnumber', cardnum);
    flutterwave.BIN.check(cardnum, function(req, res) {
      var country = res.body.data.country;
      console.log('country', country);
      callback(country);
    });
  },
};

Note the new callback parameter that gets passed in, and then called with the country value (instead of just returning it nowhere).

Use it like this,

app.post('/checkcardbin', function(req, res) {
  var cardnumber = req.body.cardnumber;
  fd.bvncheck(cardnumber, function(country) {
    var r = country;
    console.log('result', r);
  });
});

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