Вложенные запросы API в узле маршрута / экспресс - PullRequest
0 голосов
/ 28 июня 2018

Я очень новичок в кодировании, и это мой первый пост здесь. Мой учебный проект - это веб-сайт, который использует внешнюю 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});

Я почти уверен, что это работа для обещаний, однако я просто не могу разобраться с синтаксисом. Буду признателен за любую помощь, и я прошу прощения, если формат этого вопроса является любительским или каким-то образом неуместным.

1 Ответ

0 голосов
/ 28 июня 2018

Я бы предложил использовать библиотеку request-promise (которая является интерфейсом обещаний для библиотеки request), а затем использовать обещания для управления упорядочением и обработкой ошибок в серии асинхронных операций. Вы можете сделать это так:

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. Используйте обработчик .then() в возвращенном обещании, чтобы получить результат.
  4. Обработка этого результата с .map().
  5. В обратном вызове .map() верните еще одно обещание от вызова к запросу-обещанию для каждого элемента данных. Это означает, что .map() вернет массив обещаний.
  6. Используйте Promise.all() в этом массиве обещаний, чтобы знать, когда они все будут выполнены.
  7. Верните обещание из Promise.all(), чтобы оно было приковано к предыдущему обработчику .then() для секвенирования.
  8. Затем в другом обработчике .then() (который не будет вызываться до тех пор, пока обе предыдущие операции не будут полностью выполнены) вы получите данные из операции .map() в правильном порядке, которые вы можете использовать для вызова res.render().
  9. Наконец, добавьте .catch(), чтобы перехватывать любые ошибки в цепочке обещаний (все ошибки будут распространяться на это .catch(), куда вы можете отправить ответ об ошибке).
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...