NodeJS异步/等待不等待(返回Promise待处理)

时间:2019-05-07 17:36:54

标签: node.js for-loop mongoose stellar

我正在编写一个API,该API可以为用户获取过去在Stellar网络上进行的交易,在数据库中查找相应的用户,然后将它们全部合并为JSON(以响应请求-稍后)。

问题:查找与accountID(“ from”字段)相对应的用户名是一种带有猫鼬的异步方法,仅在JSON组装后才返回数据。

我尝试使用async / await,promise,.thens,但似乎无济于事。

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 个答案:

答案 0 :(得分:1)

您不能在Promises中使用普通的“ for循环”,因为循环不会等待承诺解决,而是会转到下一个迭代。您可以使用新的“ for of”循环以及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)
    })

答案 1 :(得分:1)

突出推荐,您可以根据自己的情况使用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函数中使用。

答案 2 :(得分:0)

您需要一个条件来检查您正在等待的功能是否已完成

     pattern = ['drink', 'eat', 'sleep']

     [t for t in string.split('. ') if any (l in pattern for l in t)]