Наилучшая практика для передачи данных из асинхронного вызова в nodejs с правильной резервной структурой маршрутизации - PullRequest
1 голос
/ 07 февраля 2020

У меня есть функция запроса, которая выполняет вызов к конечной точке и получает от нее данные. Затем я передаю эти данные в шаблон hbs для рендеринга, но из-за асинхронности массив, передаваемый в шаблон, пуст. Как правильно это сделать. Пожалуйста помоги. Ниже приведен фрагмент кода.

app.get("/verifier", keycloak.protect('verifier'), (req, res) => {  
  cirRes = cirJSON.parse(cirJSON.stringify(res))
  //the req object is a circular object so you cannot convert it to json normaly wihtout data loss.
  allUser = []
  access_token = cirRes.req.kauth.grant.access_token.token
  var options = { method: 'GET',
  url: 'http://localhost:8080/auth/admin/realms/create_user_realm/users',
  headers: 
   { 
     'Content-Type': 'application/x-www-form-urlencoded',
     Host: 'localhost:8080',
     Accept: '*/*',
     Authorization: `Bearer ${ access_token }` } }
  request(options, function (error, response, body) {
    if (error) throw new Error(error);
      data = JSON.parse(body)
      for (user in data){
       allUser.push(data[user])
      } 
      //console.log(allUser)
  })
  if (res.statusCode != 200) {
    res.redirect('/logout')
  }
  console.log(allUser)
  res.render('verifier', {"users": allUser})
})

В приведенном выше коде allUser представляет собой пустой массив.

edit >>>>

Этот вопрос был закрыт из-за ответ в этой теме. Как мне вернуть ответ от асинхронного вызова? Он охватывает различные способы выполнения асинхронных запросов.

Проходя через то же самое, я внес это изменение в код

app.get("/verifier", keycloak.protect('verifier'), (req, res) => {  
  cirRes = cirJSON.parse(cirJSON.stringify(res))
  //the req object is a circular object so you cannot convert it to json normaly wihtout data loss.
  //console.log(cirRes.req.kauth.grant.access_token.token)
  allUser = []
  access_token = cirRes.req.kauth.grant.access_token.token
  var options = { method: 'GET',
  url: 'http://localhost:8080/auth/admin/realms/create_user_realm/users',
  headers: 
   { 
     'Content-Type': 'application/x-www-form-urlencoded',
     Host: 'localhost:8080',
     Accept: '*/*',
     Authorization: `Bearer ${ access_token }` } }
  request(options, function (error, response, body) {
    if (error) { throw new Error(error) }
      data = JSON.parse(body)
      for (user in data){
       allUser.push(data[user])
      } 
      //console.log(allUser)
      res.render('verifier', {"users": allUser})
    })
  if (res.statusCode != 200) {
    res.redirect('/logout')
  }
})

Это прекрасно работает, но является правильным в соответствии с лучшими практиками nodeJS, и что является лучшим для этого в nodeJS, так что существует некоторый резервный механизм для рендеринга, даже если в вызове происходит ошибка.

Ответы [ 2 ]

1 голос
/ 07 февраля 2020

Переместите ваши вызовы res.render() и res.redirect() так, чтобы они находились внутри функции обратного вызова вашего вызова request(). Вот как вы используете асинхронно предоставленную информацию в express, когда хотите отправить ее в браузер пользователя или клиент API.

0 голосов
/ 07 февраля 2020

Это прекрасно. вам нужно добавить переменную option в блок try-catch.

try{
var options = { method: 'GET',
  url: 'http://localhost:8080/auth/admin/realms/create_user_realm/users',
  headers: 
   { 
     'Content-Type': 'application/x-www-form-urlencoded',
     Host: 'localhost:8080',
     Accept: '*/*',
     Authorization: `Bearer ${ access_token }` } }
  request(options, function (error, response, body) {
    if (error) { throw new Error(error) }
      data = JSON.parse(body)
      for (user in data){
       allUser.push(data[user])
      } 
      //console.log(allUser)
      res.render('verifier', {"users": allUser})
    })
  if (res.statusCode != 200) {
    res.redirect('/logout')
  }

}catch(e){
  throw(e);
} 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...