试图了解如何正确使用: app = Express().method ,相同方法和中间件中的多个 requests()

Trying to understand how to work properly with : app = Express().method , several requests() in same method and middleware

试图了解如何正确使用: 1.快递 2.请求 3. 中间件

这是来自 的后续问题,其中的讨论富有成效且很有帮助(感谢@BlazeSahlzen,你太棒了!)但我意识到我有一次试图提出太多问题(尽管他们都是相关的)进入同一个问题。 所以,这是一个重点问题...我希望 :-)

案例:我想构建 POST() 通过路径 (/:param1) 接收参数, 用它来 request() #1 一个外部 API, 从外部 API 获取结果, 使用结果做一些事情并将另一个请求()#2发送到第二个外部API, 获取第二个 APi 请求()的结果, 确定 POST 是否为 statusCode = 200 且 message="ok" 或 statusCode = something_else 且 message = "problem" 并且 res.send() 正确。

为此,这是我的伪代码 -

var middle_1 = function(req, res, next) {
         param1 = req.params.param1; //trying to access the param1 from the path, not sure it will work in middleware
         req.middle_1_output = {
             statusCode: 404,
             message: "param1"
         }
         var options = {
             method: 'PUT',
             url: `EXTERNAL_API_1`,
             headers: {
                 'cache-control': 'no-cache',
                 'content-type': 'application/x-www-form-urlencoded',
                 apikey: `KEY`
             }
         };
         request(options, function(error, response, body) {
             if (error) throw new Error(error);
             // CODE THAT DO SOMETHING AND GET INFORMATION
             req.request_1_output.statusCode = 200;
             req.request_1_output.message = "hello world";
             next(); // not sure what happens here - will it "jump" outside of the middle_1() or go to the next request() down the code??
         });
     var options = {
         method: 'PUT',
         url: `EXTERNAL_API_2`,
         headers: {
             'cache-control': 'no-cache',
             'content-type': 'application/x-www-form-urlencoded',
             apikey: `KEY`
         }
     };
     request(options, function(error, response, body) {
         if (error) throw new Error(error);

         //Can I use here the req.request_1_output.message ???
         //How can I use here ALSO some of the EXTERNAL_API_1 outcome????

         // Some more CODE THAT DO SOMETHING AND GET INFORMATION

         req.request_2_output.statusCode = 201;
         req.request_2_output.message = "hello world";
         next(); // not sure what happens here 
     });
 }

 //This middleware is only used to send success response
 var response_success = function(req, res) {
     sum_statusCode = req.request_1_output.statusCode + req.request_2_output.statusCode;
     if (req.request_2_output.message == req.request_1_output.message) {
         meassge = "hello world";
     } else {
         message = "goodbye world!";
     }
     res.json({
         "statusCode": sum_statusCode,
         "message": message
     });
 }

 app.post('/test', middle_1, response_success);
  1. 我不确定在这种情况下如何连接不同的请求(请求 #1 和请求 #2)——它们都应该成为中间件吗?我应该怎么写呢? (连接 => 让它们 运行 只有在另一个完成后才成为一个。)

  2. 如何从请求 #1 的结果中获取信息并在请求 #2 中使用它?

  3. 看看我在 response_success() 的代码 -> 这行得通吗?我可以从请求 #1 和请求 #2 中发起的 req 访问这样的数据吗?

  4. 我应该如何访问 response_success() 数据,这是请求 #1 和请求 #2 的结果?

// 已编辑 - 问题 #5 和 #6 是我的后期版本,但应该是独立的问题。我把它们留在这里,但我会专门为它们开一个新线程。

  1. 假设我的 middle_1 需要从 request_1 获取信息作为结果,计算一些东西,然后将其移至 middle_2...我如何将 request_1 信息转化为可以转移到 middle_2 中的东西?我想我应该在 "req" 中创建一个 属性 ,类似于 req.middle_1_outcome = DATA ,但我不确定如何从 [=62] "get the DATA" =] 结果...

  2. 如何在我的 middle_1 继续计算之前 "monitor and wait" 完成 request_1?是否有用于同步请求的 requestSync() 函数?

提前感谢所有帮助者:-)

给定的中间件函数在完成所有处理后应该只调用 next() 一次。

给定的请求处理程序应该只为每个请求提交一个响应。超过的内容将被 Express 视为错误。

I am not sure how to connect the different requests (request #1 and request #2) in this case - should they all become middleware? how should I write it? (connect => make them run one only after the other is done.)

如果您的两个 request() 调用可以 运行 并行(第二个调用不依赖于第一个结果),那么您可以 运行 它们两个,然后在它们何时进行监控都完成了,收集结果,对请求做你需要做的,然后只调用一次 next().

如果它们必须 运行 顺序(使用第一个的结果到第二个),那么你可以嵌套它们。

How can I get also information from the request #1 outcome and use it in the request #2 ?

有多种方法可以解决该问题。如果请求按顺序 运行,那么通常的方法是将请求 #2 放入请求 #1 的完成回调中,其中 #1 的结果是已知的。

Look at my code at response_success() -> will this work? can I access like this data from req that originated within the request #1 and request #2?

你不能那样做,因为你不能从同一个中间件多次调用 next()

How am I suppose to access inside the response_success() data which is the OUTCOME of the request #1 and request #2?

如果你嵌套这两个操作并且运行请求#2从里面完成 请求 #1,然后在请求 #2 的完成中,您可以访问这两个结果。不需要完全独立的请求处理程序来处理结果。这只会使必要的复杂化。


如果你需要序列化你的两个请求,因为你想在第二个请求中使用第一个请求的结果,那么你可以使用这个结构,将第二个请求嵌套在第一个请求的完成中:

function middle_1(req, res, next) {
    var param1 = req.params.param1; //trying to access the param1 from the path, not sure it will work in middleware
    var options = {
        method: 'PUT',
        url: `EXTERNAL_API_1`,
        headers: {
            'cache-control': 'no-cache',
            'content-type': 'application/x-www-form-urlencoded',
            apikey: `KEY`
        }
    };
    request(options, function (error, response, body) {
        if (error) return next(error);
        // CODE THAT DO SOMETHING AND GET INFORMATION
        var options = {
            method: 'PUT',
            url: `EXTERNAL_API_2`,
            headers: {
                'cache-control': 'no-cache',
                'content-type': 'application/x-www-form-urlencoded',
                apikey: `KEY`
            }
        };
        // this second request is nested inside the completion callback
        // of the first request.  This allows it to use the results from
        // from the first request when sending the second request.
        request(options, function (error2, response2, body2) {
            if (error2) return next(error2);

            // right here, you can access all the results from both requests as
            //    they are all in scope
            // response, body from the first request and
            // response2, body2 from the second request

            // When you are done with all your processing, then you 
            // can send the response here
            res.json(....);
        });
    });
}

app.post('/test', middle_1);

请注意有关此代码结构的几点:

  1. 要在第二个请求中使用第一个请求的结果,只需将两者嵌套即可。
  2. 像这样嵌套时,两个请求的结果都将在请求 #2 的完成回调中可用,只要您为参数指定唯一的名称,这样它们就不会意外地隐藏同名的父范围变量。
  3. 从异步回调中 throw 对您没有好处,因为您的代码无法捕获从普通异步回调中抛出的异常。该请求可能会永远坐在那里,直到它最终超时(如果您抛出)。您需要实际处理错误。因为我不知道你想要什么错误处理,所以我调用 next(err) 至少给你默认的错误处理。
  4. 我不建议使用实际上只是一个操作的多个中间件函数。您也可以像我展示的那样将一个操作放在一个请求处理程序函数中。