NodeJS Async / Await не ожидает (возвращает обещание в ожидании) - PullRequest
0 голосов
/ 07 мая 2019

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

Проблема: поиск имени пользователя, соответствующего accountID (поле from), является асинхронным методом с mongoose и возвращает данные только после сборки JSON.

Я пытался использовать async/ await, обещания, .ены, но, похоже, ничего не работает.

server.payments()
    .forAccount(accountId)
    .cursor('now')
    .order('desc')
    .limit(2)
    .call()
    .then(function (page) {
        var history = []
        for(var i = 0; i<page.records.length; i++){
            var obj = page.records[i]
            //Get the username corresponding to the key from my database
            //FIXME
            var username
            findUser(obj["from"]).then(result => {
                username = result
            })
            var payment = {
                "currency":obj["asset_code"],
                "from": obj["from"],
                "username":username,
                "amount": obj["amount"],
                "timestamp":obj["created_at"]
            }
            history.push(payment)
        }
        console.log(history)
        //console.log(JSON.stringify(history))
    })
    .catch((err) => {
        console.log(err)
    })

async function findUser(senderKey){
    var user = await mongoose.User.findOne({publicKey: senderKey})
    console.log(user.username)
    return user.username
}

Ожидаемый результат: findUser возвращает значение, переменная платежа использует его и регистрируется вместе.

Что происходит:findUser начинает поиск данных, переменная платежа собирается вместе (имя пользователя не определено) и регистрируется, findUser возвращает данные.

Вот журнал: (человек-паук - это фактическое имя пользователя из моей базы данных)

[ { currency: 'MEUR',
    from: 'GACRQARPR2OMWRG6IH7HM5DYTA3FMM6UKA7NKS4BIJIADRIKFRPAIE7G',
    username: undefined,
    amount: '3.0000000',
    timestamp: '2019-05-07T13:37:04Z' },
  { currency: 'MEUR',
    from: 'GACRQARPR2OMWRG6IH7HM5DYTA3FMM6UKA7NKS4BIJIADRIKFRPAIE7G',
    username: undefined,
    amount: '2.0000000',
    timestamp: '2019-05-07T13:34:21Z' } ]
spiderman
spiderman

Ответы [ 3 ]

1 голос
/ 08 мая 2019

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

Вы будете wait до тех пор, пока сервер не ответит на page, тогда каждый из obj в page.records (.map или .forEach ... приведет вас в замешательство), вы wait для findUser функция возвращает username, затем занимайтесь своими делами.

try {
  const page = await server.payments()
    .forAccount(accountId)
    .cursor('now')
    .order('desc')
    .limit(2)
    .call()
  const history = [];
  for (const obj of page.records) {
    const username = await findUser(obj["from"]);
    const payment = {
      "currency": obj["asset_code"],
      "from": obj["from"],
      "username": username,
      "amount": obj["amount"],
      "timestamp": obj["created_at"]
    }
    history.push(payment)
  }
  console.log(history)
} catch (e) {
  console.log(e)
}

Напоминание: await выражение допускается только в функции async.

1 голос
/ 08 мая 2019

Нельзя использовать обычный цикл for для Promises, поскольку цикл не будет ждать разрешения обещания и перейдет к следующей итерации.Вы можете использовать новый цикл for для async await: -

server.payments()
    .forAccount(accountId)
    .cursor('now')
    .order('desc')
    .limit(2)
    .call()
    .then(async function (page) {
        var history = []

        for(const obj of page.records) {
          const username = await findUser(obj["from"]);
            var payment = {
                "currency":obj["asset_code"],
                "from": obj["from"],
                "username":username,
                "amount": obj["amount"],
                "timestamp":obj["created_at"]
            }
            history.push(payment)
        }

        console.log(history)
        //console.log(JSON.stringify(history))
    })
    .catch((err) => {
        console.log(err)
    })
0 голосов
/ 08 мая 2019

Вам нужно условие, которое проверяет, завершила ли ожидаемая вами функция

async function findUser(senderKey){
    var user = await mongoose.User.findOne({publicKey: senderKey})
    if (user){
      console.log(user.username)
      return user.username
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...