How do I avoid deeply nested code in node.js?

后端 未结 6 2186
执念已碎
执念已碎 2021-02-08 22:28

In node.js, it being event-driven, all I/O is done via callbacks. So I end up writing code that looks like this:

app.get(\'/test\', function (req, res) {
  ht         


        
相关标签:
6条回答
  • 2021-02-08 22:59

    You could use async module to avoid this.

    0 讨论(0)
  • 2021-02-08 23:07

    Don't use anonymous functions.

    EDIT

    Your code isn't even valid. You aren't closing most of your function calls.

    If you switched to named functions it would look something like this: Updated to reflected comment about global namespace

    (function () {
        app.get('/test', f0)
    
        function f0(req, res) {
          http.get('some/place', f1)
        }
    
        function f1(req1, res1) {
            if (res1.statusCode == 200) {
              res1.on('data', f2)
            }
         }
        function f2(data) {
            http.get('other/place?q=' + data, f3)
        }
        function f3(req2, res2) {
          if (res2.statusCode == 200) {
            res2.on('data', f4)
          }
        }
    
        function f4(data) {
              db.query(data).on('data', f5)
            }
    
        function f5(rows) {
            res.writeHead(200)
            res.end(JSON.stringify(rows))
        }
    })()
    
    0 讨论(0)
  • 2021-02-08 23:13

    I wrote a library based on node-seq, which looks like this:

    app.get('/test', function (req, res) {
      Seq()
        .seq(function () {
          http.get('some/place', this.next)
        })
        .seq(function (req1, res1) {
          if (res1.statusCode == 200) {
            res1.on('data', this.next)
          }
        })
        .seq(function (data) {
          http.get('other/place?q=' + data, this.next)
        })
        .seq(function (req2, res2) {
          if (res2.statusCode == 200) {
            res2.on('data', this.next)
          }
        })
        .seq(function (data) {
          db.query(data).on('data', this.next)
        })
        .seq(function (rows) {
          res.writeHead(200)
          res.end(JSON.stringify(rows))
        })
    })
    

    The code is here.

    Also, there's a lengthy discussion on the nodejs mailing list about this issue.

    Step is another library for doing this stuff.

    0 讨论(0)
  • 2021-02-08 23:15

    Please have a look at Streamline; it is a JavaScript preprocessor that allows you to write simple 'streamlined' code and transforms it to callback-heavy code.

    0 讨论(0)
  • 2021-02-08 23:16

    You can use promises. Check this out https://github.com/kriskowal/q

    0 讨论(0)
  • 2021-02-08 23:21

    Another (and perhaps better) way to clean up this kind of thing is to use EventEmitters rather than callbacks. Here's an example showing several EventEmitters in use:

        var events = require('events'),
        util = require('util');
    
        var Search = function () {
        "use strict";
    
        var search,
            requestPageData,
            makeReturnObject,
            sendResults,
    
            emptyObj = {};
    
        events.EventEmitter.call(this);
    
        search = function (query) {
            this.emit("requestPageData", query);
        };
    
        requestPageData = function (query) {
            var resultsArray = [];
    
            // some logic
    
            if (.....some condition....) {
                this.emit("makeReturnObject", resultsArray);
            } else {
                this.emit("sendResults", emptyObj);
            }
        };
    
        makeReturnObject = function (resultsArray) {
            var resultsObj = {};
    
            if (magnetArray) {
    
                // some logic
    
                this.emit("sendResults", resultsObj);
            } else {
                this.emit("sendResults", emptyObj);
            }
        };
    
        sendResults = function (obj) {
            // finally, do whatever it is you want to do with obj
        };
    
        this.on("requestPageData", requestPageData);
    
        this.on("makeReturnObject", makeReturnObject);
    
        this.on("sendResults", sendResults);
    
        this.search = search;
    
    };
    
    util.inherits(Search, events.EventEmitter);
    module.exports = new Search();
    0 讨论(0)
提交回复
热议问题