Node.JS - Как избежать множественных вложенных обратных вызовов? - PullRequest
0 голосов
/ 16 сентября 2018

В настоящее время у меня есть приложение expressJS, и я пытаюсь получить информацию из API с помощью функции 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 ]

0 голосов
/ 16 сентября 2018

Обещания позволяют вам избежать типа вложенности обратного вызова, как вы только что показали.Посмотрите мой пример, который иллюстрирует ваш пример в форме Promise:

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

Как вы можете видеть вложенную структуру обратного вызова и заменить ее на гораздо более читаемый формат.Подробнее об обещаниях здесь .

Выше можно даже переписать, используя 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"));
    });
});
0 голосов
/ 16 сентября 2018

Проблема с этим адом обратного вызова заключается в том, что вы не используете промежуточное ПО, в котором его поддерживает экспресс-приложение.

По сути, способ написания экспресс-приложения - это обратные вызовы и так далее. Но копия в том, что это приведет к тому, что вы указали на ад обратного вызова.

Это также относится и к обещаниям, и это называется адским обещанием, когда не обрабатывается должным образом.

Лучший способ избежать этих двух шаблонов - перейти на промежуточные программные решения.

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);
0 голосов
/ 16 сентября 2018

Обещания помогут в этом, или переместят ваши обратные вызовы в их собственные выражения функций вне маршрута, а затем вызовет его в маршруте один раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...