【问题标题】:Await doesn't actually wait for an async function to completeAwait 实际上并不等待异步函数完成
【发布时间】:2022-01-18 04:32:04
【问题描述】:

我开始在我的 NodeJS 应用程序中使用 Redis 进行缓存。与互联网上的所有教程不同(例如这个:https://medium.com/geekculture/fasten-your-node-js-application-with-a-powerful-caching-mechanism-using-redis-fd76b8aa482f),我不会在调用“缓存”函数后发送res。我的“缓存”函数是一个中间件,如果找到就会返回一个值。

这里是调用函​​数的地方:

const { requestLDAP } = require('../utils/ldap')
router.get('/:mode/:type/:code', async (req, res) => {

  (...)

  const resultLDAP = await requestLDAP(
    type, params
  );
  console.log('---');
  console.log(resultLDAP);
  console.log('---');

这是 LDAP 模块的一部分:

async function requestLDAP(type, params) {
    const key = JSON.stringify({type,params});
    // checking the cache
    await clientRedis.get(key, async (err, response) => {
      if (response) {
        console.log("[CACHE]");
        return {
          ok: true,
          contenu: JSON.parse(response),
        };
      } else {
        const simulated = Array.from({ length: 5 }, () => {
          let r = { type: type.slice(0, -1) };
          params.forEach((k) => {
            r[k] = `${cle}_${Math.floor(100*Math.random(100))}`;
          });
          return r;
        });
        console.log("[API]");
        await clientRedis.setex(cle, 10, JSON.stringify(simulated));
        console.log('[SAVED]');
        return {
          ok: true,
          contenu: simulated,
        };
      (...)

剩下的我就不写了,基本上都是实际的 LDAP 调用。

我的问题是脚本似乎没有等待“等待”完成。这是我在控制台中的内容:

---
undefined
---
---
undefined
---
[CACHE]
[CACHE]

我在这里缺少什么? 如果我写console.log(response) 我有正确的回应,但再次预期之后。

[编辑] 在有用的 cmets 之后,这是我编写函数的方式:

let finalResponse = await clientRedis.get(cle, async (err, response) => {
  if (response) {
    console.log("[CACHE]");
    return response;
  } else {
    (...)
return {
  ok: true,
  contenu: finalResponse,
};

但finalResponse 是一个布尔值,它不会返回真正的response。

【问题讨论】:

  • 您没有从您的 requestLDAP 函数返回任何内容。
  • 它可能应该是return await clientRedis.get(),因为您现在只需在回调中返回它
  • 您错误地使用了 Redis 库,您正在将回调与 async/await 混合使用。
  • 您需要“承诺”clientRedis.get 调用。这是good resource 解释如何做到这一点。
  • 我编辑了我的答案,“异步”部分很好,响应的内容很奇怪,虽然......

标签: node.js async-await redis


【解决方案1】:

正如他们之前所说,requestLDAP 函数不返回任何内容,而不是您可以等待的实际 Promise。

你需要 requestLDAP 返回一个 Promise,因为你在等待 clientRedis 的结果,你不知道什么时候会得到它。

当你拥有它时,你必须解决或拒绝提到的 Promise。这里的return不是requestLDAP的return,而是callback的调用者的return。

尝试像这样打包并返回一个承诺:

async function requestLDAP(type, params) {
  return new Promise( async (resolve,reject) => { // --> Promisify the asynchronous response
    const key = JSON.stringify({type,params});
    // checking the cache
    await clientRedis.get(key, async (err, response) => {
      if(err) reject('Something ugly happened here'); // --> Give a result for the promise in the future
      if (response) {
        console.log("[CACHE]");
        resolve( { // --> Give a result for the promise in the future
          ok: true,
          contenu: JSON.parse(response),
        } );
      } else {
        const simulated = Array.from({ length: 5 }, () => {
          let r = { type: type.slice(0, -1) };
          params.forEach((k) => {
            r[k] = `${cle}_${Math.floor(100*Math.random(100))}`;
          });
          return r;
        });
        console.log("[API]");
        await clientRedis.setex(cle, 10, JSON.stringify(simulated));
        console.log('[SAVED]');
        resolve( { // --> Give a result for the promise in the future
          ok: true,
          contenu: simulated,
        } );
      (...)
      }
    });
  }
};

【讨论】:

    猜你喜欢
    • 2019-06-16
    • 2023-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-04
    • 2019-11-29
    • 2018-09-23
    • 2020-12-23
    相关资源
    最近更新 更多