【问题标题】:NodeJS - Promise returns undefined object inside a redis pool awaitNodeJS - Promise 在 redis 池等待中返回未定义的对象
【发布时间】:2019-03-28 10:56:43
【问题描述】:

我有一个从 redis-connection-pool 创建的 Redis 池对象。它寻找一个键来获取所有图像标识符的数组。然后,对于每个元素,都会查找另一个 Redis 键,以便将值附加到一个 JSON 对象中。该对象作为对GET 请求的响应返回。

出于某种奇怪的原因(也许是 Redis 错误?),当 Promise 使用正确的数据解析时,使用此 Promise 的函数总是看到一个 undefined 对象。

最初的尝试

async function allImageData() {
    var configPool = redisPools.configPool;
    var resp = {};
    var images = [];
    var imageDetails = {};
    //
    await configPool.get('allImages', async (err, reply) => {
        if (err) {
            resp = {
                'data': {}
            }
            reject(resp)
        } else {
            if (reply === null) {
                resp = {
                    'data': {}
                }
                reject(resp)
            } else {
                imageDetails = JSON.parse(reply)
                images = imageDetails['allImages']
                return new Promise(function (resolve, reject) {
                    imageDetailsCache(images).then(function (result) {
                        resp = {
                            'data': result
                        }
                        resolve(resp) //Correct data; but, received as undefined
                    }).catch(function (result) {
                        resp = {
                            'data': {}
                        }
                        reject(resp)
                    })
                })
            }
        }
    })
}

下一次尝试

Promise 在 Redis get 结束后返回。

async function allMachineData() {
    var configPool = redisPools.configPool;
    var resp = {};
    var images = [];
    var imageDetails = {};
    //
    await configPool.get('allImages', async (err, reply) => {
        if (err) {
            resp = {
                'data': {}
            }
            reject(resp)
        } else {
            if (reply === null) {
                resp = {
                    'data': {}
                }
                reject(resp)
            } else {
                imageDetails = JSON.parse(reply)
                images = imageDetails['allImages']
            }
        }
    })
    return new Promise(function (resolve, reject) {
        // images array is empty; so, received as empty object
        imageDetailsCache(images).then(function (result) {
            resp = {
                'data': result
            }
            resolve(resp)
        }).catch(function (result) {
            resp = {
                'data': {}
            }
            reject(resp)
        })
    })
}

【问题讨论】:

  • 请注意 .get() 使用 callback 机制,它确实返回 Promise, await 常量或 void没有效果。
  • 但是我在回调中返回了一个 Promise。第二次尝试怎么样?
  • 你在两次尝试中都用.get做同样的事情
  • 检查get是否返回一个promise ...尝试添加await configPool.get( .....).then(result => result)如果你没有得到一个错误,那么get返回一个promise,如果你得到一个错误那么你会更好地理解 Neverever 的评论
  • 你还在 get 回调中使用了reject(resp)...这是什么reject 函数?

标签: node.js redis promise


【解决方案1】:

在你的尝试中你使用

await configPool.get('allImages', async (err, reply) => {

首先,.get 不返回承诺,所以awaiting 这没有意义
其次,你没有在回调中使用 await,所以不需要让它 async

看来你的代码可以简化

首先,由于您要返回一个 Promise,请将 configPool.get 包装在一个 Promise 中,这将在回调中解决/拒绝

之后,这只是一个承诺链接的问题,因为您的代码暗示imageDetailsCache 返回一个承诺,这很简单:

function allImageData() {
    return new Promise((resolve, reject) => {
        redisPools.configPool.get('allImages', (err, reply) => err ? reject(err) : resolve(reply));
    })
    .then(reply => {
        if (reply === null) return Promise.reject(null);
        const imageDetails = JSON.parse(reply);
        return imageDetailsCache(imageDetails.allImages);
    })
    .then(data => ({data}))
    .catch(() => Promise.reject({data:{}}));
}

【讨论】:

  • 此解决方案有效 - 谢谢!如果你不介意,你能解释一下then(data => ({data})) 的语法吗?我正在尝试then(function (result) {Promise.resolve(result)}) - 它显示了奇怪的错误。
  • data => ({data}) === function(data) { return {data:data};}
  • 如果configPool.get 做了reject(err),我应该在哪里放置.catch()
  • .catch(() => Promise.reject({data:{}})); 捕获所有拒绝 - 并且表现得像您的代码一样
猜你喜欢
  • 2014-06-01
  • 1970-01-01
  • 2021-07-17
  • 1970-01-01
  • 1970-01-01
  • 2016-07-19
  • 2018-09-18
  • 2018-05-20
  • 2018-09-10
相关资源
最近更新 更多