【问题标题】:Nested API requests in a route node/express路由节点/快递中的嵌套 API 请求
【发布时间】:2018-06-28 02:40:04
【问题描述】:

我对编码很陌生,这是我在这里的第一篇文章。我的学习项目是一个使用外部 CRM 来存储来自网络表单的客户数据的网站。

我的存储部分工作正常,但不知道如何检索数据并将其传递给呈现的页面。 我需要一条路线来执行 3 次操作,每个操作都可以单独正常运行,我只是不知道如何嵌套它们以便它们按顺序发生。

  1. 从 CRM 获取交易详情
var options = { method: 'GET',
                    url: 'https://crm.com/dev/api/opportunity/' + req.params.id,
                    headers: 
                        { 'cache-control': 'no-cache',
                         'content-type': 'application/json',
                          accept: 'application/json',
                          authorization: 'Basic xxx' },
                          json: true };
            request(options, function (error, response, body) {
                if (error) throw new Error(error);
                    return body.contact_ids;
            });

这将返回与交易关联的客户编号数组。

  1. 遍历客户端编号以查找来自每个客户端的数据,并放入数组。我在函数范围之外定义了一个名为 data 的空数组来捕获结果。

         resultFromAboveRequest.forEach(function(id) {               
            var options = { method: 'GET',
                 url: 'https://crm.com/dev/api/contacts/' + Number(id),
                 headers: 
                  { 'cache-control': 'no-cache',
                     'content-type': 'application/json',
                     accept: 'application/json',
                     authorization: 'Basicxxx' },
                    json: true };
    
             request(options, function (error, response, body) {
    
                if (error) throw new Error(error);
                data.push(body);
            });
        });
    
  2. 在页面上渲染结果数据数组

    res.render("./applicants/resume", {data: data});

我很确定这是一项承诺的工作,但是我似乎无法理解语法。任何帮助都将不胜感激,如果这个问题的格式是业余的或在某种程度上不合适,我深表歉意。

【问题讨论】:

  • 请不要在异步回调中写入if (error) throw new Error(error);。它没有任何用处,也无法被您的任何代码捕获。您需要弄清楚如何实际处理您的错误。
  • 好的,感谢您的反馈。我想我需要弄清楚很多事情,但我必须从某个地方开始:-)。我对此很陌生,我只是从邮递员那里复制并粘贴了代码。

标签: javascript api express


【解决方案1】:

我建议使用request-promise 库(它是request 库的promise 接口),然后使用promise 来管理一系列异步操作中的排序和错误处理。你可以这样做:

const rp = require('request-promise');

const options = {
    method: 'GET',
    url: 'https://crm.com/dev/api/opportunity/' + req.params.id,
    headers: {
        'cache-control': 'no-cache',
        'content-type': 'application/json',
        accept: 'application/json',
        authorization: 'Basic xxx'
    },
    json: true
};
rp(options).then(body => {
    return Promise.all(body.contact_ids.map(id => {
        const options = {
            method: 'GET',
            url: 'https://crm.com/dev/api/contacts/' + Number(id),
            headers: {
                'cache-control': 'no-cache',
                'content-type': 'application/json',
                accept: 'application/json',
                authorization: 'Basicxxx'
            },
            json: true
        };
        return rp(options);
    }));
}).then(data => {
    res.render("./applicants/resume", {data: data})
}).catch(err => {
    console.log(err);
    res.status(500).send("internal server error");
});

以下是步骤的一般说明:

  1. 加载请求承诺库。它不是采用完成回调,而是返回一个通过响应正文解析的承诺,或者如果出现错误则被拒绝。
  2. 发出第一个请求。
  3. 对返回的 Promise 使用 .then() 处理程序以获取结果。
  4. 使用.map() 处理结果。
  5. .map() 回调中,从每个数据项的request-promise 调用中返回另一个promise。这意味着.map() 将返回一组承诺。
  6. 在该承诺数组上使用 Promise.all() 以了解它们何时全部完成。
  7. Promise.all() 返回承诺,以便将其链接到前一个.then() 处理程序以进行排序。
  8. 然后,在另一个.then() 处理程序中(直到前面的两个操作都完成后才会调用它),您将从.map() 操作中以正确的顺序获取数据,您可以使用它来调用@987654333 @。
  9. 最后,添加.catch() 以捕获承诺链中的任何错误(那里的所有错误都会传播到.catch(),您可以在其中发送错误响应)。

【讨论】:

    猜你喜欢
    • 2020-03-27
    • 2018-11-07
    • 1970-01-01
    • 2020-08-09
    • 1970-01-01
    • 2023-01-29
    • 2015-12-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多