【问题标题】:Node.js waiting for an async Redis hgetall call in a chain of functionsNode.js 在函数链中等待异步 Redis hgetall 调用
【发布时间】:2020-04-09 04:41:12
【问题描述】:

我对使用 Node 还是有点陌生​​,而对于异步工作和使用 Promise,我还是很陌生。

我有一个应用程序正在访问 REST 端点,然后调用一系列函数。这条链的末端是调用hgetall,我需要等到我得到结果并将其传回。我正在使用 Postman 进行测试,我得到的是 {} 而不是 id。我可以console.log id,所以我知道这是因为某些代码在继续之前没有等待hgetall 的结果。

我正在使用await 等待hgetall 的结果,但这仅适用于链的末端。我是否需要为整个功能链执行此操作,或者有没有办法让一切都在继续之前等待结果?这是逻辑链的最后一点:

注意:我已从以下函数中删除了一些逻辑并重命名了一些内容,以便更轻松地查看流程以及此特定问题的情况。所以,其中一些可能看起来有点奇怪。

对于这个例子,它将调用GetProfileById()

 FindProfile(info) {
    var profile;
    var profileId = this.GenerateProfileIdkey(info); // Yes, this will always give me the correct key
    profile = this.GetProfileById(profileId);
    return profile;
}

这会检查 Redis exists,以验证密钥是否存在,然后尝试使用该密钥获取 id。我现在知道 Key() 返回 true 而不是 Redis 实际返回的内容,但是一旦我解决了当前的问题,我会修复它。

 GetProfileById(profileId) {
    if ((this.datastore.Key(profileId) === true) && (profileId != null)) {
        logger.info('GetProfileById ==> Profile found. Returning the profile');
        return this.datastore.GetId(profileId);

    } else {
        logger.info(`GetProfileById ==> No profile found with key ${profileId}`)
        return false;
    }
}

GetId() 然后调用 data_store 来获取 id。这也是我开始使用 await 和 async 来尝试等待结果出来的地方,然后再继续。这部分确实在等待结果,但在此之前的函数似乎并没有等待这个返回任何东西。也很好奇为什么它只返回键而不是值,但是当我在hgetall 中打印出结果时,我得到了键和值?

async GetId(key) {
var result = await this.store.RedisGetId(key);
    console.log('PDS ==> Here is the GetId result');
    console.log(result); // returns [ 'id' ]
    return result;
  }

最后,我们接到了hgetall 电话。同样,promise 和 async 的新手,因此这可能不是处理此问题的最佳方法或根本不是正确的方法,但它正在获取结果并在返回任何内容之前等待结果

 async RedisGetId(key) {
      var returnVal;
      var values;
      return new Promise((resolve, reject) => {
          client.hgetall(key, (err, object) => {
            if (err) {
              reject(err);
            } else {
              resolve(Object.keys(object));
              console.log(object); // returns {id: 'xxxxxxxxxxxxxx'}
              return object;
            }
          });
        });
      }

我是否需要对可能最终进行 Redis 调用的每个函数进行异步处理,或者有没有办法让应用等待 Redis 调用返回某些内容,然后继续?

【问题讨论】:

    标签: node.js asynchronous redis


    【解决方案1】:

    简短的回答是“是”。一般来说,如果一个调用发出一个异步请求,而你需要等待应答,你就需要做一些事情来等待它。

    有时,您可以使用Promise.all 同时发出多个调用await 并同时发出多个调用。

    但是,在您的情况下,您的工作流程似乎是同步的,因此您需要单独等待每个步骤。这可能会变得很丑陋,所以对于 redis,我通常使用 promisify 之类的东西,这样可以更轻松地在 redis 中使用原生 Promise。 redis 文档中甚至还有an example on how to do this

    const {promisify} = require('util');
    const getAsync = promisify(client.get).bind(client);
    ...
    const fooVal = await getAsync('foo');
    

    让你的代码更好看。

    【讨论】:

    • 谢谢。我使用了 Promisfy,我只运行了所有同步代码并返回了执行异步调用所需的值。然后,只需在 promise 返回后进行调用并使用 .then() 发送响应即可。所以像: var obj = getAsync(key); getAsync.then(function(obj){ res.send(obj) });
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-08-01
    • 2013-07-24
    • 1970-01-01
    • 1970-01-01
    • 2013-08-03
    • 1970-01-01
    • 2021-01-24
    相关资源
    最近更新 更多