Дождитесь завершения вызова API axios в Node / Express

#node.js #express #axios #ejs

#node.js #экспресс #axios #ejs

Вопрос:

Я уверен, что этот код — беспорядок, поскольку мне никогда не приходилось работать с вызовом API, подобным этому. Проблема, с которой я сталкиваюсь, заключается в том, что в производственной среде узел не ожидает завершения вызова axios перед рендерингом страницы.

У меня нет проблем с его запуском в среде разработки.

 router.get('/:id', middleware.isLoggedIn, (req, res) => {
var perPage = 9
var page = req.params.page || 1
User.findById(req.params.id)
.populate({
    path : 'log',
    options : { 
        sort : { date : -1 },
        limit: 8,
        skip: (perPage * page) - perPage
    },
  }).exec((err, foundUser) => {
    if(err){
        req.flash('error', 'Something went wrong. User not found.');
        res.redirect('back');
    } else {
        Logbook.find({author: req.user.id}).countDocuments().exec((err, count) => {
            if (err) return next(err)
            axios.get('http://data.fcc.gov/api/license-view/basicSearch/getLicenses?searchValue='   foundUser.username   'amp;format=json')
                .then(async response => {
                    var json = response.data;
                    if (json == undefined || json.Licenses == undefined || json.Licenses.License == undefined) {
                        if (err) {
                            console.log(err);
                        }
                        console.log('error1');
                        res.redirect('/profile/'   foundUser.id);
                    } else {
                        var data = json.Licenses;
                        var data2 = data.License;
                        var lic = [];
                        for (var i = 0; i < data2.length; i  ) {
                            var lic = data2[i];
                        }
                        res.render('profile/index', {
                            user: foundUser,
                            json: lic,
                            current: page,
                            pages: Math.ceil(count / perPage),
                            logCount: count,
                        });
                    };
                })
                .catch(error => {
                    console.log(error);
                    res.redirect('/profile/'   foundUser.id);
                });
        });
    }
});
 

Любая помощь искренне приветствуется!

Ответ №1:

Ваше async ключевое слово находится в странном месте, и вы не указали await , что узел должен ожидать результата этой операции.

Вообще говоря, вы помечаете функцию как async , и в этом асинхронном блоке вы можете await отображать результаты асинхронных операций.

 async function asyncFunc() {
  try {
    const response = await axios.get("/some_url_endpoint");
    const data = await response.json();
    return data;
  } catch (error) {
    console.error(error);
  }
}
 

Ваш пример может быть переписан следующим образом:

 async function searchLicenses(foundUser) {
  const { username, id } = foundUser;
  const url = `http://data.fcc.gov/api/license-view/basicSearch/getLicenses?searchValue=${username}amp;format=json`;

  try {
    const response = await axios.get(url); // node will wait for the response before continuing
    const json = response.data;
  
    if (json == undefined || json.Licenses == undefined || json.Licenses.License == undefined) {
      if (err) {
        console.log(err);
      }
      console.log('error1');
      res.redirect(`/profile/${id}`);
    } else {
      const data = json.Licenses;
      const data2 = data.License;
      const lic = [];

      for (var i = 0; i < data2.length; i  ) {
        var lic = data2[i];
      }

      res.render('profile/index', {
        user: foundUser,
        json: lic,
        current: page,
        pages: Math.ceil(count / perPage),
        logCount: count,
      });
    };
  } catch (error) {
    console.log(error);
    res.redirect(`/profile/${id}`);
  }
}

router.get('/:id', middleware.isLoggedIn, (req, res) => {
  var perPage = 9
  var page = req.params.page || 1

  User.findById(req.params.id)
    .populate({
      path: 'log',
      options: {
        sort: { date: -1 },
        limit: 8,
        skip: (perPage * page) - perPage
      },
    })
    .exec((err, foundUser) => {
      if (err) {
        req.flash('error', 'Something went wrong. User not found.');
        res.redirect('back');
      } else {
        Logbook.find({ author: req.user.id }).countDocuments().exec((err, count) => {
          if (err) return next(err)
          searchLicenses(foundUser.username)
        });
      }
    });
}

 

Комментарии:

1. Это сделало свое дело! Большое спасибо за краткий ответ. Это было очень полезно. В итоге я вернул обратный вызов и переместил res.render внутри вызова функции.