Где я иду не так, используя обещания и асинхронные? - PullRequest
0 голосов
/ 02 ноября 2019

Я написал функцию в файле apiCalls.js и имею следующую функцию:

function getAllData() {
  new Promise(function(resolve, reject) {
    async.parallel([
      function(callback) {
        request('http://urlcall', function(error, response, body) {
          if(!error && response.statusCode == 200) {
            return callback(null, body);
          }
          return callback(error || new Error('Response non-200'));
        });
      },
      function(callback) {
        request('http://urlcall', function(error, response, body) {
          if(!error && response.statusCode == 200) {
            return callback(null, body);
          }
          return callback(error || new Error('Response non-200'));
        });
      },
    ],
    function(err, results) {
      if(err) {
        console.log(err);
        reject(err);
      }
      console.log(results);
      resolve(results);
    });
  });
}

Затем я вызываю эту функцию в моем файле app.js:

apiCalls.getAllData().then(function(returned) {
    console.log(returned);
    res.render('home');
  });

Я получаю сообщение об ошибке, когда возвращаемое значение не определено: TypeError: Cannot read property 'then' of undefined

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

1 Ответ

1 голос
/ 02 ноября 2019

Во-первых, вы действительно не хотите смешивать обещания с простыми обратными вызовами с библиотекой async. Вам нужно выбрать одну модель для работы (обещания или обратные вызовы) и запрограммировать весь поток управления в одной модели. Итак, если вы переходите к обещаниям (а это большая часть мира), то полностью пропустите асинхронную библиотеку. В этом конкретном случае Promise.all() служит вашим целям для двух параллельных запросов.

Затем обратите внимание на то, чтобы пообещать асинхронные операции самого низкого уровня, которые у вас есть, так как они позволяют использовать обещания для всего потока управления и обработки ошибок. В вашем случае это библиотека запросов, которая уже имеет обещанную версию под названием request-prom. Кроме того, он уже автоматически проверяет для вас статус не-2xx (и отклоняет обещание), поэтому вам не нужно его кодировать. Таким образом, кажется, вы можете заменить все, что у вас есть, только на это:

const rp = require('request-promise');    // promise version of the request library

function getAllData() {
    return Promise.all([rp('http://urlcall1'), rp('http://urlcall2')]);
}

Затем вы можете использовать его с .then():

apiCalls.getAllData().then(returned => {
    console.log(returned);
    res.render('home', returned);
}).catch(err => {
    console.log(err);
    res.sendStatus(500);
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...