Действительно перепутан с JS async (вызов 2 API)

1

Так простое объяснение того, что я делаю. Во-первых, я принимаю запрос GET от конечного пользователя. Во-вторых, я передаю параметр (я сейчас делаю GET-запрос) из запроса get к функции async, которая возвращает адрес электронной почты пользователя на основе параметра (по существу, URL-адрес сундука "Боб" и "Роберт Ричардсон").

В-третьих, я делаю более полный запрос GET ко второй системе, которая возвращает файл JSON, содержащий разные лакомые кусочки о пользователе.

Я знаю, что выноски работают нормально, потому что я могу запустить node index.js с функцией, в которой я вручную node index.js нужную мне информацию, и возвращает желаемые результаты. Но когда я запускаю свой nodejs-сервер и пытаюсь ответить на входящий запрос GET (я тестирую, определенно не живу), я получаю очень странные результаты...

Вот что я пытаюсь получить в данный момент://server.js const express = require ('express'); const bodyParser = require ('body-parser'); const app = express(); const port = 8000;

app.use(bodyParser.urlencoded({
  extended: true
}));

require('./app/routes')(app, {});
app.listen(port, () => {
  console.log('test is listening on port :: ' + port);
});

//routes.js
const getdata = require('./getData '); //contains function for GET request one to convert param to email


async function getReturn(app, db) {
  app.get('/getDataFrom/:alias', (req, res) => {
    const alias = req.params.alias;
    console.log('alias : ' + alias);
    getEmailFromPromise(alias);

  });


}

async function getEmailFromPromise(alias) {
  console.log('getting email');
  let output = await getEmail(alias);
  console.log('output :: ' + output);
  // return output;
}

function getEmail() {
  return new Promise(resolve => {
    let email = getdata.getUserInfo(alias);
    resolve(email);
  }, 1000);
}

Стоит отметить, что JS и Node - это не то, что я обычно кодирую, но мне нужен проект, с которым я помогаю. Я могу получить простые примеры для работы, но не мои запросы.

Прохождение в GET: localhost: 8000/getDataFrom/bob

Вышеприведенное возвращает следующее:

test is listening on port :: 8000
alias : rrichardson
getting email
output :: undefined   //I am wanting this to log after I actually get the email
email found :: [email protected]   //I do get this back, but out of order. The undefined above should also be this

Другой файл, если он помогает (он экспортируется правильно):

//this is callout one getData 

async function getUserInfo(alias){
client.connect();
client.query('select email, firstname, lastname from salesforce.user WHERE 
alias = \''+ alias + '\'', (err, res) => {
if (err) console.log('err :: ' + err);
// console.log(res.rows);
   client.end();
   var email = res.rows[0].email;
   if(email != null){
     console.log('email found :: ' + email);
     return email;
    } 
    else return 'No Email Found';
  });
}

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

Спасибо!

Теги:
async-await
promise
get

2 ответа

1
Лучший ответ

Вам нужно getReturn чтобы вернуть обещание, сгенерированное вызовом getEmailFromPromise. Поскольку app.get использует обратный вызов, а не обещание, вам придется явно преобразовать его в обещание сначала - и в этом случае не так много использовать при создании getReturn async.

function getReturn(app, db) {
  return new Promise((resolve) => {
    app.get('/getDataFrom/:alias', (req, res) => {
      const alias = req.params.alias;
      console.log('alias : ' + alias);
      getEmailFromPromise(alias)
        .then(resolve);
    });
  });
}

Другая проблема заключается в том, что getUserInfo также использует обратные вызовы, а не обещания - вы не можете просто превратить его в функцию async, вам придется явно преобразовать его, чтобы вернуть Promise:

function getUserInfo(alias){
  return new Promise((resolve, reject) => {
    client.connect();
    client.query('select email, firstname, lastname from salesforce.user WHERE 
                 alias = \''+ alias + '\'', (err, res) => {
      if (err) {
        console.log('err :: ' + err);
        reject(err);
      }
      // console.log(res.rows);
      client.end();
      var email = res.rows[0].email;
      if(email != null){
        console.log('email found :: ' + email);
        resolve(email);
      } 
      else resolve('No Email Found');
    });
  });
}

Вам также нужно использовать await чтобы использовать обещания, если вы хотите, чтобы строка ниже запускалась только после того, как обещание было разрешено:

function getEmail() {
  return new Promise(resolve => {
    let email = await getdata.getUserInfo(alias);

Но нет смысла await чего-то, что обещание, если вы собираетесь немедленно его решить. (и второй аргумент, который вы предоставляете обещанию в getEmail, 1000, не имеет никакого смысла)

Просто верните обещание:

function getEmail() {
  return getdata.getUserInfo(alias);
}
  • 0
    Это было очень полезно, спасибо. У меня это частично работает после прочтения вашего поста и применения некоторых из них. Сейчас я работаю над получением второй части того, над чем я работал. Обещания все еще очень новы для меня, но это действительно помогло им обрести смысл. Ценить это!
1

вы смешиваете асинхронные и обещания, этого избежать. Ваша проблема в том, что функция getUserInfo является асинхронной, но у нее нет части "ожидания", она не ждет "разрешения" или возврата, так что она ничего не возвращает или "неопределенная", потому что вы ссылаетесь на это сообщение электронной почты "let email = getdata. GetUserInfo (псевдоним);" вы можете использовать primse на этом этапе, некоторые из них:

function getUserInfo(alias){
    return new Promise(function(resolve, reject){
        client.connect();
        client.query('select email, firstname, lastname from salesforce.user WHERE alias = \''+ 
                 alias + '\'', (err, res) => {
            if (err) reject('err :: ' + err);
            // console.log(res.rows);
            client.end();
            var email = res.rows[0].email;
            if(email != null){
                console.log('email found :: ' + email);
                resolve(email);
            } 
            else reject('No Email Found');
        });
    }
}

и назовите его:

function getEmail() {
    return new Promise(resolve => {
        getdata.getUserInfo(alias).then(function(email){
            resolve(email);
        });
    });
}
  • 0
    Я использовал это вместе с постом CertainPerformance. Это помогло. Большое спасибо!

Ещё вопросы

Сообщество Overcoder
Наверх
Меню