node.js~构造Promise的链式序列解析 [英] node.js ~ constructing chained sequence of Promise resolves

查看:135
本文介绍了node.js~构造Promise的链式序列解析的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人能建议一种更好的方法来构建Promises的使用吗?
我对Promises很新,我想知道我是否遗漏了一些关于如何构建这一系列事件的事情。

Can anyone suggest a better way to structure this use of Promises? I'm newish to Promises and am wondering if I'm missing something about how to construct this a chain of events.

注意:这是我的意图不要在这里使用rej [ect]。
你看到guatanrees只有res [olve]返回。这意味着返回的代码只需要一个路径来处理返回的值。
因此返回的代码在它的流程中更简单。

Note: It IS my intention to NOT use the rej[ect] here. What you see guatanrees only the res[olve] returns. Meaning the code this returns to only needs one path with which to handle the returned value. Thereby the code returned to is simplier in it's flow.

如果你不认识它,可能会有所帮助,这是从模块中获取的我建立。把它想象成Dao。

It might help to know, if you don't recognize it, this is taken from a module I created. Think of it as a Dao.

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');
            });
        });
    }
};


推荐答案

关于承诺的关键要点是然后 返回一个新的承诺(和 catch 一样)。如何解决新的承诺取决于您从处理程序返回的内容:如果您返回承诺,则来自的新承诺 / catch 从属于您返回的那个;如果您返回一个值,则使用该值解析新的承诺。

The key thing to remember about promises is that then returns a new promise (as does catch). How that new promise is settled depends on what you return from the handler: If you return a promise, the new promise from then/catch is slaved to the one that you returned; if you return a value, the new promise is resolved with that value.

因此您可以将它们链接在一起。将然后 catch 处理程序想象为转换过滤器的最终结果。

So you can chain them together. Think of the then and catch handlers as transforming filters the ultimate result flows through.

另请注意,如果您有一个给您承诺的起点( cn.connect()),则不需要 new Promise :只需使用然后 catch 来转换通过通过返回(新)分辨率值来链。

Note also that if you have a starting point that gives you a promise (cn.connect()), you don't need new Promise: Just use then and catch to transform what passes through the chain by returning the (new) resolution value.

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

Another key thing to remember is that if a catch handler returns a value, it converts a rejection into a resolution. To continue down the rejection path, a catch handler must either throw an exception or return a promise that is/will be rejected.

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

Finally: require calls should always be at the beginning of the module.

所以,不删除您将拒绝转换为决议(稍后会详细介绍):

So, without removing your conversion of rejections to resolutions (more on that in a moment):

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]。你看到guatanrees只有res [olve]返回。这意味着返回的代码只需要一个路径来处理返回的值。因此返回的代码在它的流程中更简单。

Note: It IS my intention to NOT use the rej[ect] here. What you see guatanrees only the res[olve] returns. Meaning the code this returns to only needs one path with which to handle the returned value. Thereby the code returned to is simplier in it's flow.

拒绝遵循决议的单独路径有一个原因。它不会使事情变得更复杂,它使事情更简单。不要将拒绝转换为决议,除非你做了某种错误恢复,并且可以继续进行,就好像没有发生拒绝一样。

Rejections follow a separate path from resolutions for a reason. It doesn't make things more complicated, it makes things simpler. Don't convert rejections into resolutions unless you're done an error-recovery of some kind and can continue on as though the rejection hadn't happened.

这是代码拒绝被拒绝的地方:

Here's that code where rejections are allowed to be rejections:

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.
    });

我也可能抽出一些我认为你最终会反复做的事情:建立连接并从中获取请求对象:

I'd also probably abstract out the bit I assume you'll end up doing over and over: Establishing a connection and getting a request object from it:

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';
                        });
                });
        });
    }
};

这篇关于node.js~构造Promise的链式序列解析的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆