【问题标题】:NodeJS nested promiseNodeJS 嵌套承诺
【发布时间】:2018-07-09 06:36:01
【问题描述】:

我有一个场景,我必须使用 AWS lambda 从 Redis 获取数据。

  1. 连接到 redis
  2. 从 redis HASH 中获取 key 的数据。 (对 redis 的异步调用)
  3. 如果您从第 2 步获取数据(它将返回 JSON 数据),则在 JSON 中进行操作
  4. 如果您从第 2 步获取数据,则调用另一个异步 API,该 API 将从 redis 获取数据并将其添加到之前收到的 JSON 中。
  5. 如果在第 4 步出现任何错误(拒绝),则返回错误。

  6. 如果您从第 2 步中获取 null,则从另一个哈希中获取数据 使用相同的键(异步调用 redis)

  7. 如果您从第 6 步获取数据(它将返回 JSON 数据),则在 JSON 中进行操作
  8. 如果您从第 6 步获取数据,则调用另一个异步 API,该 API 将从 redis 获取数据并将其添加到之前收到的 JSON 中。
  9. 如果在第8步发生任何错误(拒绝),则返回错误。

  10. 断开与 redis 的连接。

现在我不确定使用这些嵌套和依赖调用编写干净的代码 nodeJS。

redisConnection.on('connect', function(){ //Step 1
cache.getFromHash(hash1, key) //Step2
.then(data => {
    if(data){
        data.cost = 1000; // step3
        cache.getMultipleFromHash(hash3, keys) //step4
        .then(moredata => {
            data.moredata = moredata;
            const response = {
                statusCode: 200,
                body: JSON.stringify(data),
            };
            redisConnection.quit();
            callback(null, response);
        })
        .catch(err => { // step5
            const response = {
                statusCode: 200,
                body: JSON.stringify({"err": err}),
            };
            redisConnection.quit();
            callback(null, response);
         })
    } else {
        cache.getFromHash(hash2, key) // step6
        .then(defaultData => {
            defaultData.cost = 1000; // step7
            cache.getMultipleFromHash(hash3, keys) //step8
            .then(moreData => {
                data.moreData = moreData;
                const response = {
                    statusCode: 200,
                    body: JSON.stringify(data),
                  };
                  redisConnection.quit();
                callback(null, response);
            })
            .catch(err => { // Step 9
                const response = {
                    statusCode: 200,
                    body: JSON.stringify({"err": err}),
                };
                redisConnection.quit();
                callback(null, response);
             })
        })
        .catch(err => {
            const response = {
                statusCode: 200,
                body: JSON.stringify({"err": err}),
            };
            redisConnection.quit();
            callback(null, response);
        })
    }
})
.catch(err => {
    const response = {
        statusCode: 200,
        body: JSON.stringify({"err": err}),
    };
    redisConnection.quit();
    callback(null, response);
})
})

在这段代码中我们可以看到:
1. 第 3 步和第 7 步 - 重复步骤
2. 第 4 步和第 8 步 - 重复步骤
3.多个catch块
4.多次返回和关闭连接。

如果我在同步编程中编写相同的代码,那么它将是这样的(假设的):

   redisConnection.on('connect', function(){
    let data = cache.getFromHash(hash1, key)
    if (! data) {
            data = cache.getFromHash(hash2, key)
    }
    let moreData = cache.getMultipleFromHash(hash3, keys)
    data.cost = 1000;
    data.moreData = moreData;
    connection.quit();
    return data;
})

我们可以让这个异步代码更清晰还是没有选项?

提前致谢!

【问题讨论】:

  • 你看过async/awaitPromise的语法
  • 尝试以更好的方式使用承诺链。
  • 尝试了 async/await 和链接两者,但仍然不是很干净的代码。
  • 当我必须在 for 循环中运行多个键时,情况会变得更加复杂。
  • 您可以检查 aync(caolan.github.io/async) 库并使用 async 函数逐个执行并调用 next。我相信 caolan.github.io/async/docs.html#series 作为 Iterable 的函数列表应该可以解决您的问题。

标签: node.js redis aws-lambda


【解决方案1】:

你可以试试这样的。

async yourFunction(){
redisConnection.on('connect', function(){ //Step 1
    try{
      let data = await cache.getFromHash(hash1, key) //Step2
      if(data){
        data.cost = 1000;
        let moredata = await cache.getMultipleFromHash(hash3, keys);
        data.moredata = moredata;
        const response = {
            statusCode: 200,
            body: JSON.stringify(data),
        };
        redisConnection.quit();
        callback(null, response);
      }
      else{
        let defaultData = await cache.getFromHash(hash2, key);
        defaultData.cost = 1000; // step7
        let moreData = await cache.getMultipleFromHash(hash3, keys) //step8
        data.moreData = moreData;
        const response = {
            statusCode: 200,
            body: JSON.stringify(data),
          };
          redisConnection.quit();
        callback(null, response);
      }
    }
    catch(error){
      const response = {
          statusCode: 200,
          body: JSON.stringify({"err": err}),
      };
      redisConnection.quit();
      callback(null, response);
    }
  }
}

yourFunction().then(result => console.log(result))

如果您想要自定义错误处理,您可以将每个 await 包装在 try catch 块中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-02-25
    • 2019-10-28
    • 1970-01-01
    • 1970-01-01
    • 2019-05-22
    相关资源
    最近更新 更多