当前位置: 首页 > 面试题库 >

node.js〜构建Promise解决方案的链式序列

司空福
2023-03-14
问题内容

谁能建议一种更好的方式来组织对Promises的使用?我是Promises的新手,想知道我是否缺少有关如何构建一系列事件的信息。

注意:我的意图是在此处不使用rej [ect]。您看到的保证只有res
[olve]返回。这意味着返回到的代码仅需要一个路径来处理返回的值。这样,返回的代码就更简单了。

如果您不认识它,这可能会帮助我从我创建的模块中获取信息。认为它是一个刀。

module.exports = {

    dbConnection: function () {
        return { user: 'sa', password: 'mypassword', server: 'localhost', database: 'mydb' };
    },


    CanIConnectToTheDB: function () {
        return new Promise(function (res, rej) {
            var sql = require('mssql');
            var myDao = require('./myDao');
            var cn = new sql.ConnectionPool(myDao.dbConnection());

            cn.connect().then(function () {
                var req = new sql.Request(cn);
                var qry = 'select serverproperty(\'productversion\') as \'rs\'';
                req.query(qry)
                    .then(function (rs) {
                        qry = 'select isnull(object_id(\'SomeObjectIKnowExists\'), -1)';
                        req.query(qry)
                            .then(function (rss) {
                                res(' CONNECTED// MASTER DB SUCCESS// MY DB SUCCESS');
                            })
                            .catch(function (err) {
                                res(' CONNECTED// MASTER DB SUCCESS// ISSUE QUERYING MY DB //' + err + '//');
                            });
                    })
                    .catch(function (er) {
                        res(' CONNECTED// COULD NOT QUERY MASTER DB //' + er + '//');
                    });
            })
            .catch(function () {
                res(' CAN NOT CONNECT');
            });
        });
    }
};

问题答案:

关于诺言,要记住的关键是then 返回一个新的诺言
(与一样catch)。新诺言的结算方式取决于您从处理程序返回的内容:如果您返回诺言,则来自then/
的新诺言将成为您返回的诺言的catch奴隶;如果您返回一个值,则使用该值来解析新的promise。

因此,您可以将它们链接在一起。将thencatch处理程序视为最终结果流经的转换过滤器。

还要注意,如果您有一个给您诺言(cn.connect())的起点,则不需要new Promise:只需使用thencatch通过返回(新)分辨率值来变换通过链的内容。

要记住的另一项关键是,如果catch处理程序返回一个值,它将把拒绝转换为分辨率。要继续沿拒绝路径前进,catch处理程序必须抛出异常或返回将被/将被拒绝的承诺。

最后:require调用应始终位于模块的开头。

因此,无需删除拒绝项到解决方案的转换(稍后会介绍更多内容):

var sql = require('mssql');
var myDao = require('./myDao');

module.exports = {

    dbConnection: function () {
        return { user: 'sa', password: 'mypassword', server: 'localhost', database: 'mydb' };
    },


    CanIConnectToTheDB: function () {
        var cn = new sql.ConnectionPool(myDao.dbConnection());
        return cn.connect()
            .then(function () {
                var req = new sql.Request(cn);
                var qry = 'select serverproperty(\'productversion\') as \'rs\'';
                return req.query(qry)
                    .then(function (rs) {
                        qry = 'select isnull(object_id(\'SomeObjectIKnowExists\'), -1)';
                        return req.query(qry)
                            .then(function (rss) { // Note you're not using rss anywhere
                                return ' CONNECTED// MASTER DB SUCCESS// MY DB SUCCESS';
                            })
                            .catch(function (err) {
                                return ' CONNECTED// MASTER DB SUCCESS// ISSUE QUERYING MY DB //' + err + '//';
                            });
                    })
                    .catch(function (er) {
                        return ' CONNECTED// COULD NOT QUERY MASTER DB //' + er + '//';
                    });
            })
            .catch(function() {
                return ' CAN NOT CONNECT';
            });
    }
};

注意:我的意图是在此处不使用rej [ect]。您看到的保证只有res
[olve]返回。这意味着返回到的代码仅需要一个路径来处理返回的值。这样,返回的代码就更简单了。

出于某种原因,拒绝遵循与决议不同的路径。它不会使事情变得更复杂,而是使事情变得 更简单
。除非您进行了某种类型的错误恢复,并且可以继续进行,好像拒绝没有发生,否则请不要将拒绝转换为解决方案。

这是允许拒绝成为拒绝的代码:

var sql = require('mssql');
var myDao = require('./myDao');

module.exports = {

    dbConnection: function () {
        return { user: 'sa', password: 'mypassword', server: 'localhost', database: 'mydb' };
    },

    CanIConnectToTheDB: function () {
        var cn = new sql.ConnectionPool(myDao.dbConnection());
        return cn.connect()
            .then(function () {
                var req = new sql.Request(cn);
                var qry = 'select serverproperty(\'productversion\') as \'rs\'';
                return req.query(qry)
                    .then(function (rs) {
                        qry = 'select isnull(object_id(\'SomeObjectIKnowExists\'), -1)';
                        return req.query(qry)
                            .then(function (rss) { // Note you're not using rss anywhere
                                return ' CONNECTED// MASTER DB SUCCESS// MY DB SUCCESS';
                            });
                    });
            });
    }
};

使用它:

theModule.CanIConnectToTheDB()
    .then(function() {
        // Yes, let's do something
    })
    .catch(function() {
        // No, report the problem, etc.
    });

我可能还会抽象出我认为您将一遍又一遍地做的事情:建立连接并从中获取请求对象:

var sql = require('mssql');
var myDao = require('./myDao');

function getRequest() {
    var cn = new sql.ConnectionPool(myDao.dbConnection());
    return cn.connect().then(function() {
        return new sql.Request(cn);
    });
}

module.exports = {

    dbConnection: function () {
        return { user: 'sa', password: 'mypassword', server: 'localhost', database: 'mydb' };
    },

    CanIConnectToTheDB: function () {
        return getRequest().then(function(req) {
            var qry = 'select serverproperty(\'productversion\') as \'rs\'';
            return req.query(qry)
                .then(function (rs) {
                    qry = 'select isnull(object_id(\'SomeObjectIKnowExists\'), -1)';
                    return req.query(qry)
                        .then(function (rss) { // Note you're not using rss anywhere
                            return ' CONNECTED// MASTER DB SUCCESS// MY DB SUCCESS';
                        });
                });
        });
    }
};


 类似资料:
  • 我对Javascript相当陌生,希望在谈到如何解决promise的顺序时,能对async/await做一点澄清。 假设我有一个异步函数,我们称之为foo,它检索某些内容,然后使用fs将其写入文件。promise图书馆。 我还有另一个异步函数,它将调用foo,然后在写入文件内容后对其进行处理——在网页上显示,进行计算,等等。 我希望确保在执行otherFileFunc之前,文件内容已写入,即wri

  • Hyperledger Composer使架构师和开发人员能够快速创建“全堆栈”区块链解决方案。即业务逻辑运行在区块链上运行,REST API将区块链逻辑暴露给Web或移动应用程序,以及将区块链与现有企业记录系统集成在一起。 Hyperledger Composer由以下高级组件组成: 执行运行时(目前支持四个!) JavaScript SDK 命令行接口 REST服务器 LoopBack连接器

  • 请告诉我如何解决这个问题。我更新了Xamarin表单dll。 我得到以下错误: 错误错误:找不到符号专用本机void n\u onInflate(android.support.v7.widget.ViewStubCompat p0,android.view.view p1);符号:class ViewStubCompat位置:package android。支持v7.widget obj\Deb

  • 救急,我導入的maven項目怎麽構建報錯,我自己下了jdk但是好像他構建用的不是我下載的,我又不知道怎麽更換 環境變量也設置了,但是他用的不是我下載和設置的jdk,我安裝在D盤,他用的是D盤的jdk,求大佬解答 ======== 上面的問題解決了但是還是報錯:

  • 我有以下代码: 我这样嘲笑: 在几行代码之后,会出现另一个链式方法调用: 我这样嘲笑: 所以我的问题是,我找不到比这更好的解决方案,因为问题是如果我告诉mockito将null返回给处理程序而不是iTspProcessorManagementHandler,那么我在(1)处得到一个nullpoer异常,但如果我对我的代码进行以下更改: 而不是mockito嘲笑每个方法调用,并且我的当-时返回语句不

  • 问题内容: 我正在尝试创建由4个项目组成的ASP.NET 5解决方案的映像。结构如下: FlashTools(ASP.NET 5类库) 模型(ASP.NET 5类库) QuizzCorrector(ASP.NET 5 Web应用程序) QuizzService(ASP.NET 5类库) 我有一个简单的Dockerfile,看起来像这样: 但不确定放在哪里。在我的解决方案的根文件夹中global.j