在节点js中将异步函数转换为同步?

时间:2017-08-03 11:58:23

标签: javascript node.js asynchronous

我正在使用API​​,希望我通过卡片的前四位数字,然后返回卡片国家/地区。现在,这是我的问题。事实证明,我调用的函数是异步的,当我尝试返回该国家时,它甚至在异步调用完全执行之前就会转到返回值。我希望调用是同步的,这意味着我不希望函数返回默认数据并等待来自API的实际响应。这是我到目前为止所尝试的。我实际上使用了console.log()语句来弄清楚整个问题。

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);
});

我期望按以下顺序输出以下内容 -

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

但实际上,它按以下顺序返回我,并且由于异步性质,我得到的结果是未定义的,因为数据在函数实际执行之前返回。

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

我该如何解决这个问题?任何建议或建议都非常感谢。

4 个答案:

答案 0 :(得分:3)

我必须通过包含回调来更改您的模块。因此fd.bvncheck将等待回调。

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);
        });

    });

答案 1 :(得分:1)

您可以使用Promise.all。这是一个很好的解释: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

答案 2 :(得分:1)

您可以使用承诺

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);
  });
});

答案 3 :(得分:1)

bvncheck功能编写不正确。它是异步的,但它没有提供传递回调的方法。由于目前已经编写,因此无法从bvncheck函数外部访问返回的国家/地区。 return country;行没有任何价值。看起来应该更像这样,

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);
    });
  },
};

请注意传入的新callback参数,然后使用国家/地区值调用(而不是仅将其返回)。

像这样使用,

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