【问题标题】:Best way to handle the nodejs promise处理 nodejs 承诺的最佳方式
【发布时间】:2018-11-18 22:04:59
【问题描述】:

我是 nodejs 和 promises 的新手。这是我通过阅读一些文章编写的代码,但我觉得我没有走上正确的道路。

问题:- 在 getManager() 中,有时 neo4j db 在运行查询时会抛出错误,因此控制最终会出现在 catch 块中。然而,不知何故,在那之后承诺将不会得到解决。所以我不确定我是否需要打电话 在 catch 块中的 deferred.reject(returnResults)。

1) BOT对话框消费者:调用getPersonInfo()

helper.getPersonInfo(personFullName)
    .then(function(results) {
        if (results && results.length >= 1) {
            //Do something.
        } else {
            //Do something.
        }
    })
    .catch(function(error) {
        //Do something
    });

2) getPersonInfo() 的外观:

getPersonInfo: function(fullname) {
    return Promise.all([
                    personService.getManager(firstname, fullname, operatorId),
                    personService.getTeamsMates(firstname, fullname, operatorId)
                ]);
}

3) promise.all() 方法之一的外观:-

var Q = require('q')

getManager: function(fullname) {
    let session = graphDBDriver.session();
    let deferred = Q.defer();
    let query = function() {
        let returnResults = [];
        if (fullname) {

            let cypherQuery = "Neo4j Query"

            session
                .run(cypherQuery, { fullname: fullname })
                .then(function(result) {
                    result.records.forEach(function(record) {
                        if (record && record.length >= 1) {
                            returnResults.push(record);
                        }
                    });

                    return deferred.resolve(returnResults);

                    session.close();

                })
                .catch(function(error) {
                    session.close();
                    console.log(" Neo4j error from getManager: " + error);


                });
        } else {
            return deferred.reject(returnResults);
        }
    }
    query();
    return deferred.promise;
}

问题:-

1) 在 getManager() 的 catch 块中使用 deferred.reject(returnResults) 是个好习惯吗?

2)我应该根据最佳实践进行任何其他模式或代码更改吗?

【问题讨论】:

标签: node.js promise q deferred


【解决方案1】:
  1. 在 getManager() 的 catch 块中使用 deferred.reject(returnResults) 是个好习惯吗?

    不,永远不要拒绝与拒绝原因无关的任何事情。


  1. 我应该根据最佳实践进行任何其他模式或代码更改吗?

    • session.then(...) 中,session.close(); 永远不会在return 语句之后执行。

    • 您不必在query() 中嵌入session.run(...) 逻辑。此外,如果 session.run().then().catch() 将返回 Promise,您可以直接返回它,而不是初始化新的 Promise 并显式解析/拒绝。

    • session.catch(...) 中的error 也应由deferred.reject 处理,而不仅仅是将其记录到控制台。

    • 如果你不使用古老的 Node.js,它应该有原生的 Promise,你不必使用“Q”。

这就是我将如何实现getManager

getManager : function (fullname) {
    // ideally, `fullname` should be checked before calling this function
    // if this function is only for private use and totally controllable.
    if (fullname) {
        // only initialize variables when necessary
        const returnResults = [];
        const session = graphDBDriver.session();
        const cypherQuery = "Neo4j Query";
        return session
            .run(cypherQuery, {
                fullname: fullname
            })
            .then(function(result) {
                result.records.forEach(function(record) {
                    if (record && record.length >= 1) {
                        returnResults.push(record);
                    }
                });
                session.close();
                // `return value` in `.then()` is similar to `resolve(value)`
                return returnResults;
            })
            .catch(function(error) {
                session.close();
                console.log(" Neo4j error from getManager: " + error);
                // `throw value` in `.catch()` is similar to `reject(value)`
                // throw it so that it can be caught
                throw error;
            });
    } else {
        const error = new Error('`fullname` is required');
        // always return a promise
        return Promise.reject(error);
    }
}

【讨论】:

  • 感谢@Kitce 的详细解释。关于模块'Q'你是说我不需要使用 let deferred = Q.defer();我认为使用 deferred.promise 有一些优势。
  • 是的,当你的逻辑已经返回一个 Promise 时,没有必要初始化一个新的 Promise。此外,除非您需要本机 Promise 中不存在的东西,否则您不需要 Q。比如我用“bluebird”表示Promise,因为我通常用它的Promise.propsPromise.map等等。
  • 即便如此,Q.defer 也是反模式。如果 native 或其他 promise 需要转换为 Q,则为 Q(promise)Q.when(promise)。作为原生 Promise 中不存在的东西,有 ponyfills,它们可以与原生 Promise 一起以功能方式使用(自从引入 async..await 以来,有充分的理由更喜欢它们)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-26
  • 2020-03-19
  • 2022-01-27
  • 2014-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多