如何让nodejs的多个http请求全部响应回来后才让程序往下走

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何让nodejs的多个http请求全部响应回来后才让程序往下走相关的知识,希望对你有一定的参考价值。

参考技术A var request=require('request');
Promise.all([url1,url2,url3].map(function(url)
return new Promise(function()
request(url,function(err,resopnse,body)
resolve(
err:err,
body:body
)
)
)
)).then(function(results)
//result是一个数组,里面包含http请求回来的页面代码或者错误信息

)

NodeJS 通过请求函数加入承诺

【中文标题】NodeJS 通过请求函数加入承诺【英文标题】:NodeJS joining promise with request functions 【发布时间】:2021-04-19 03:48:24 【问题描述】:

我有以下用于 clover 支付 api 的代码,虽然代码运行良好,但当我从邮递员调用 api 时,我没有得到响应。我知道这是因为服务中有多个请求,我试图找到一种更清洁的方法来做到这一点,但一直未能让它发挥作用。我正在尝试发回最终响应,即 postPayment() 函数中请求的响应。任何帮助将不胜感激。

我的服务代码是:

const db = require('../_helpers/db');
const crypto = require('crypto');
const request = require("request-promise");


module.exports = 
    getAll
;

var targetEnv = 'https://sandbox.dev.clover.com/v2/merchant/';
var cardNumber = '6011361000006668';

async function getAll(data) 
  var url = targetEnv + data.merchant_id + '/pay/key';

  var options = 
    url: url,
    method: 'GET',
    headers: 
      Authorization: 'Bearer ' + data.api_token
    
  ;

  request(options, (error, response, body) => 
    if (!error && response.statusCode === 200) 
      console.log('getAll ' +data);
      processEncryption(JSON.parse(body), JSON.stringify(data));
    
  );


// Process the encryption information received by the pay endpoint.
function processEncryption(jsonResponse, data) 
  console.log('processEncryption ' +data);
  var prefix = jsonResponse['prefix'];
  var pem = jsonResponse['pem'];

  // create a cipher from the RSA key and use it to encrypt the card number, prepended with the prefix from GET /v2/merchant/mId/pay/key
  var encrypted = crypto.publicEncrypt(pem, Buffer(prefix + cardNumber));

  // Base64 encode the resulting encrypted data into a string to Clover as the 'cardEncrypted' property.
  var cardEncrypted = new Buffer(encrypted).toString('base64');

  return postPayment(cardEncrypted, data);


// Post the payment to the pay endpoint with the encrypted card information.
async function postPayment(cardEncrypted, body) 
  // POST to /v2/merchant/mId/pay
  console.log('mid ' +JSON.parse(body));
  var posturl = targetEnv + '9ZQTAJSQKZ391/pay';
  var postData = 
    "orderId": "4N3RBF33EBEGT",
    "currency": "usd",
    "amount": 2,
    "tipAmount": 0,
    "taxAmount": 0,
    "expMonth": 12,
    "cvv": 123,
    "expYear": 2018,
    "cardEncrypted": cardEncrypted,
    "last4": 6668,
    "first6": 601136,
    "streetAddress": "123 Fake street",
    "zip": "94080",
    "merchant_id": "9ZQTAJSQKZ391",
    "order_id": "4N3RBF33EBEGT",
    "api_token": "4792a281-38a9-868d-b33d-e36ecbad66f5"
  

  var options = 
    url: posturl,
    method: 'POST',
    headers: 
      'Authorization': 'Bearer ' + "4792a281-38a9-868d-b33d-e36ecbad66f5",
    ,
    json: postData
  ;

   request(options, (error, response, body) => 
    if (!error && response.statusCode === 200) 
      //console.log(response);  
      return response;   <---- this response is what i need to show in postman
    
  );
   console.log(response);

我的控制器是:

const express = require('express');
const router = express.Router();
const tableOrderService = require('./cloverPayment.service');

// routes
router.post('/getAll', getAll);


module.exports = router;


function getAll(req, res, next) 
    tableOrderService.getAll(req.body)
        .then(users => res.json(users))
        .catch(err => next(err));

【问题讨论】:

您必须将res 作为参数传递给processEncryption()postPayment(),然后使用res.send(...)request() 回调中的postPayment() 中发送最终响应。而且,您还有多个地方需要通过发送错误响应来进行适当的错误处理。你不能直接返回值,就像你试图让它是异步的一样,你只是返回到你的回调中,因为函数早在值可用之前就已经返回了。 @jfriend00 感谢您的回复,它不起作用。当我尝试传递 res 时,它给出了一个错误。你能举个例子吗? 【参考方案1】:

您的异步函数 getAll()postPayment() 未正确返回异步值(通过回调或承诺)。

我建议将所有内容都转换为 Promise,并从 getAll()postPayment() 返回一个 Promise。而且,由于转换为 Promise,我将删除已弃用的 request-promise 库以支持 got() 库。然后,您可以调用getAll(),返回一个承诺并使用解析值或拒绝从实际请求处理程序发送您的响应:

const db = require('../_helpers/db');
const crypto = require('crypto');
const got = require('got');

module.exports = 
    getAll
;

var targetEnv = 'https://sandbox.dev.clover.com/v2/merchant/';
var cardNumber = '6011361000006668';

async function getAll(data) 
    console.log('getAll ', data);
    const url = targetEnv + data.merchant_id + '/pay/key';

    const options = 
        url: url,
        method: 'GET',
        headers: 
            Authorization: 'Bearer ' + data.api_token
        
    ;
    const response = await got(options);
    return processEncryption(response, data);


// Process the encryption information received by the pay endpoint.
function processEncryption(jsonResponse, data) 
    console.log('processEncryption ' + data);
    const prefix = jsonResponse.prefix;
    const pem = jsonResponse.pem;

    // create a cipher from the RSA key and use it to encrypt the card number, prepended with the prefix from GET /v2/merchant/mId/pay/key
    const encrypted = crypto.publicEncrypt(pem, Buffer(prefix + cardNumber));

    // Base64 encode the resulting encrypted data into a string to Clover as the 'cardEncrypted' property.
    const cardEncrypted = Buffer.from(encrypted).toString('base64');
    return postPayment(cardEncrypted, data);


// Post the payment to the pay endpoint with the encrypted card information.
function postPayment(cardEncrypted, body) 
    // POST to /v2/merchant/mId/pay
    console.log('mid ', body);
    const posturl = targetEnv + '9ZQTAJSQKZ391/pay';
    const postData = 
        "orderId": "4N3RBF33EBEGT",
        "currency": "usd",
        "amount": 2,
        "tipAmount": 0,
        "taxAmount": 0,
        "expMonth": 12,
        "cvv": 123,
        "expYear": 2018,
        "cardEncrypted": cardEncrypted,
        "last4": 6668,
        "first6": 601136,
        "streetAddress": "123 Fake street",
        "zip": "94080",
        "merchant_id": "9ZQTAJSQKZ391",
        "order_id": "4N3RBF33EBEGT",
        "api_token": "4792a281-38a9-868d-b33d-e36ecbad66f5"
    

    const options = 
        url: posturl,
        method: 'POST',
        headers: 
            'Authorization': 'Bearer ' + "4792a281-38a9-868d-b33d-e36ecbad66f5",
        ,
        json: postData
    ;

    return got(options);

然后,你的控制器:

const express = require('express');
const router = express.Router();
const tableOrderService = require('./cloverPayment.service');

// routes
router.post('/getAll', (req, res) => 
    tableOrderService.getAll(req.body)
        .then(users => res.json(users))
        .catch(err => next(err));
);

module.exports = router;

【讨论】:

非常感谢,你的例子确实澄清了很多东西,我终于让它工作了。

以上是关于如何让nodejs的多个http请求全部响应回来后才让程序往下走的主要内容,如果未能解决你的问题,请参考以下文章

NodeJS 通过请求函数加入承诺

nodejs http请求,req.abort和re.destory的区别是啥

NodeJS在某些任务后发送响应

如何从 POST 请求中检索 cookie?

nodejs的http模块不是能够立即接收/发送整个请求/响应吗?

nodejs - 在其他请求后无法响应[重复]