【问题标题】:Promise.resolve returns UndefinedPromise.resolve 返回未定义
【发布时间】:2018-10-02 03:06:26
【问题描述】:

这是Multiple Promises - Where to resolve? 的延续,我将相同的代码用于不同的功能。

然而,这一次 Promise.resolve 返回 undefined。

结果 感谢许多人指出错误。我意识到自己提交的代码中有多个错误。

1) 在非布尔运算中使用 &&。

应该使用

(console.log(results) , Promise.resolve(results)

而不是

console.log(results) && Promise.resolve(results)

2) 使用不需要的 Promise.resolve - 仅从 Async 函数返回结果将产生与使用 Promise.resolve 相同的结果。

我的最终代码。

getMessages: function (roomId) {

    return keysAsync('room:'+roomId)
    .then(room => 
        room === '' ? Promise.reject('Invalid room Id')
                    : smembersAsync('room:messages:'+roomId))
        .then(messagesId => { return messagesId })
        .catch(err => { return err }))

}

原始问题 我正在使用 nodejs promisify,所以我将以下内容声明为 Redis 的承诺

const { promisify } = require('util');
const getAsync = promisify(client.get).bind(client);
const hmsetAsync = promisify(client.hmset).bind(client);
const hsetAsync = promisify(client.hset).bind(client);
const incrAsync = promisify(client.incr).bind(client);
const smembersAsync = promisify(client.smembers).bind(client);
const keysAsync = promisify(client.keys).bind(client);
const sismemberAsync = promisify(client.sismember).bind(client);

getMessages: function (roomId) {

    return keysAsync('room:'+roomId)
    .then(room => 
        room === '' ? Promise.reject('Invalid room Id')
                    : smembersAsync('room:messages:'+roomId))
        .then(messagesId => console.log(messagesId) && Promise.resolve(messagesId))
        .catch(err => Promise.reject(err))

},

然后我如下调用函数

tools.getMessages('4').then((results) => {
    console.log('Messages in Room 4 => ', results);
  }).catch(err => console.log(err))

在我的控制台中,我可以看到以下结果

[ '191', '192', '193', '194', '195', '196', '197',
“198”、“199”、“200”、“201”、“202”、“207”、“208”、“209”、 '210'、'211'、'212'、'213'、'214'、'215'、'216'、'217'、 '218' ] //这是我控制台日志messageId的时候

4 号房间的消息 => 未定义 //这是我控制台记录结果的时候

【问题讨论】:

  • 这些对Promise.resolvePromise.reject 的调用都没有必要或有用。
  • 而且Promise.all() 似乎也没有必要。
  • 最后一个.then()返回未定义的console.log()的值。
  • 然而,尽管如此,这可能不是问题所在。我们需要查看keysAsyncsmembersAsync 的(MCVE 版本)。请使用 minimal reproducible example 来更新您的问题,以展示问题,最好是使用 Stack Snippets([<>] 工具栏按钮;here's how to do one可运行
  • @JJJ:是的。我认为 OP 提到的 undefined 是它记录的那个,但是......

标签: javascript promise


【解决方案1】:

console.log() 返回undefined,这是错误的。 && 是一个短路运算符,仅当第一个表达式为真时才计算第二个表达式。所以它永远不会执行Promise.resolve(messagesId)

使用逗号运算符代替&&。它计算两个表达式并返回第二个。

    .then(messagesId => (console.log(messagesId), Promise.resolve(messagesId)))

【讨论】:

  • 或者停止尝试将多个语句塞进一个语句中,并使用带有两个语句的大括号(IMO 更具可读性的解决方案)。
  • 为什么还要使用Promise.resolve()。这似乎没有必要。
  • 我看了那行,看到了|||| 不在那里,但这是我看到的。叹息。
  • +1 用于建议逗号运算符,-1 用于在示例代码中不使用它。您不能在简洁的箭头正文中使用逗号运算符 - 您实际上是在使用两个参数调用 then
  • @Bergi 谢谢。我什至在一两天前回答了一个关于逗号运算符的危险性的问题,但我掉进了陷阱。
【解决方案2】:

正如已经解释的那样,由于&& 的工作方式和console.log() 返回的内容,您将得到console.log(messagesId) 的返回值作为解析值undefined

但是,既然您在这里真正想要做的就是记录结果并继续使用相同的解析值,我建议一种更简洁的方法是让自己成为一个小实用函数:

function log(arg) {
    console.log(arg);
    return arg;
}

然后,你可以改变这个:

.then(messagesId => console.log(messagesId) && Promise.resolve(messagesId))

到这里:

.then(log)

请注意,在.then() 处理程序中,您返回的任何普通值都将成为承诺链的解析值。如果你想在 Promise 链中添加另一个异步操作,你也可以返回一个 Promise,但如果你已经有了一个值,你可以只需要 return value;。你不需要return Promise.resolve(value);。在 .then() 处理程序中,Promise.resolve() 只是额外的、不必要的代码 - 只需直接返回值。

【讨论】:

    【解决方案3】:

    Promise 无法使用 messageId 解析,因为 console.log() 返回 undefined

    console.log(Boolean(console.log("test")));

    但这不是你唯一应该改变的,事实上,你可以省略很多,因为smembersAsync()函数返回一个promise,你可以简单地返回:

    而不是

    return keysAsync('room:'+roomId)
        .then(room => 
            room === '' ? Promise.reject('Invalid room Id')
                        : smembersAsync('room:messages:'+roomId))
            .then(messagesId => console.log(messagesId) && Promise.resolve(messagesId))
            .catch(err => Promise.reject(err))
    

    简单地使用

    return keysAsync('room:'+roomId)
        .then(room => {
            if (room === "") { Promise.reject('Invalid room Id') } 
            else return smembersAsync('room:messages:'+roomId)
        })
    

    【讨论】:

    • 这里没有未解决的承诺。有一个解析值为undefined
    • 我的代码中未解决的承诺在哪里?我要么返回 a 承诺,要么在给定条件下拒绝一个承诺
    • 您的第一句话说“承诺永远不会解决”。这是不正确的。
    • 那么,这个承诺会发生什么?
    • 它的解析值为undefined。这与根本没有解决完全不同。
    猜你喜欢
    • 2019-11-17
    • 1970-01-01
    • 1970-01-01
    • 2021-07-23
    • 2016-11-18
    • 2019-12-24
    • 2016-05-15
    • 2017-03-11
    • 2019-07-09
    相关资源
    最近更新 更多