代码之家  ›  专栏  ›  技术社区  ›  newang

Node.JS -如何避开多个嵌套回调?

  •  2
  • newang  · 技术社区  · 6 年前

    我目前有一个expressJS应用程序,我正在尝试使用 getStats 功能。然而 profile

    function getStats(access_token, time_range, x, callback) {
        var stats = [];
    
        var options = {
            url: 'www.example.com',
            headers: {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            },
            json: true
        }
    
        request(options, function(error, response, body) {
            if (!error && response.statusCode == 200) {
                for (i = 0; i < body.items.length; i++) {
                    stats.push(body.items[i].name);
                }
                return callback(stats);
            }
        })
    
    }
    
    app.get('/profile', function(req, res) {
        var access_token = 1234;
    
        getStats(access_token, 's', 'x', function(a){
            console.log(a);
    
            getStats(access_token, 's', 'y', function(b){
                console.log(b);
    
                getStats(access_token, 'm', 'x', function(c){
                    console.log(c);
    
                    getStats(access_token, 'm', 'y', function(d){
                        console.log(d);
    
                        getStats(access_token, 'l', 'x', function(e){
                            console.log(e);
    
                            getStats(access_token, 'l', 'y', function(f){
                                console.log(f);
    
                                res.send(a + "\n" + b + "\n" + c + "\n" + d + "\n" + e + "\n" + f);
                            });
                        });
                    });
                });
            });
        });
    });
    
    3 回复  |  直到 6 年前
        1
  •  7
  •   etarhan    6 年前

    承诺允许您避免像刚才所示的回调嵌套类型。请看我的例子,它以承诺的形式说明了你的例子:

    function getStats(access_token, time_range, x, prevResult) {
        return new Promise((resolve, reject) => {
            if (prevResult) {
                resolve([...prevResult, "test", "test", "test"]);
            } 
            return resolve(["test", "test", "test"]);
    
        });
    }
    
    app.get('/profile', (req, res) => {
        var access_token = 1234;
    
        getStats(access_token, 's', 'x')
            .then((a) => {
                console.log(a);
                return getStats(access_token, 's', 'y', a);
            })
            .then((b) => {
                console.log(b);
                return getStats(access_token, 'm', 'x', b);
            })
            .then((c) => {
                console.log(c);
                return getStats(access_token, 'm', 'y', c);
            })
            .then((d) => {
                console.log(d);
                return getStats(access_token, 'l', 'x', d);
            })
            .then((e) => {
                console.log(e);
                return getStats(access_token, 'l', 'y', e);
            })
            .then((f) => {
                console.log(f);
                res.send(f.join("\n"));
        });
    });
    

    here .

    上面的内容甚至可以用 Promise.all ,看起来更漂亮:

    function getStats(access_token, time_range, x) {
        return new Promise((resolve, reject) => {
            return resolve(["test", "test", "test"]);
        });
    }
    
    app.get('/profile', (req, res) => {
        var access_token = 1234;
    
        Promise.all([
            getStats(access_token, 's', 'x'),
            getStats(access_token, 's', 'y'),
            getStats(access_token, 'm', 'x'),
            getStats(access_token, 'm', 'y'),
            getStats(access_token, 'l', 'x'),
            getStats(access_token, 'l', 'y')
        ]).then((values) => {
            console.log(values);
            res.send(values.join("\n"));
        });
    });
    
        2
  •  1
  •   Trevor Johnson    6 年前

        3
  •  0
  •   Alejandro Vales user1768079    6 年前

    避免这两种模式的最佳方法是进入中间件解决方案。

    function getAccesstoken(req, res, next) {
        if (!req.something) {
            return next('Error, something was not specified');
        }
        req.someRequestVariable = 'set_something';
        next();
    }
    
    function processRequest(req, res, next) {
        console.log(req.someRequestVariable);
        res.send(200);
    }
    
    app.use(function genericHandlerForEveryCall() {
        console.log('This is being called in every request');
    })
    
    app.get('/profile', getAccesstoken, processRequest);