Почему положение инструкции next () меняет поведение моего приложения? - PullRequest
0 голосов
/ 09 октября 2019

Я следовал документации Keystone для создания нового проекта. Я пытаюсь создать страницу, которая ведет себя по-разному в зависимости от того, вошел ли пользователь в систему или нет.

Моя страница мопса выглядит примерно так:

extends ../layouts/default

block content
    if(!user)
        .container: .jumbotron
            .row
                .col-md-2
                .col-md-8.text-center.welcome
                    h2 Welcome
                .col-md-2
    else
        .container: .jumbotron
            .row
                .col-md-2
                .col-md-8.text-center.welcome
                    h2 Logged in
                .col-md-2
            .row

Мои index.js имеютэто в конце для выставления конечных точек:

// Setup Route Bindings
exports = module.exports = function (app) {
    // Views
    app.get('/', routes.views.index);
    app.all('/signin', routes.views.signin);
};

И файл JavaScript, который обслуживает конечную точку маршрутизации signin:

var keystone = require('keystone');
var User = keystone.list('User');
var bcrypt = require('bcrypt');

exports = module.exports = function (req, res) {

    var view = new keystone.View(req, res);
    var locals = res.locals;
    var utente = req.body.utente;
    var passwd = req.body.password;

    // locals.section is used to set the currently selected
    // item in the header navigation.
    locals.section = 'home';

    view.on('init', function(next){
        next();
    });

    view.on('post', { action: 'signin' }, function (next) {
        // console.log("utente: " + utente);

        User.model.find()
            .where('email', utente)
            .exec()
            .then(function (user) { //first promise fulfilled
                //return another async promise

                console.log("user: ", user);
                console.log("email: ", user[0].email);
                console.log("password: ", user[0].password);

                bcrypt.compare(passwd, user[0].password, function(err, res) {
                    if(res){
                        console.log("Signin OK!");
                        locals.user = user[0];
                    }else{
                        console.log("Wrong Email or Password!");
                        req.flash("error", "wrong email or password!");
                    }
                });

            }, function (err) { //something happened
                //catch the error, it can be thrown by any promise in the chain
                console.log(err);
            });

        next();
    });

    // Render the view
    view.render('index');
};

Но моя страница мопса не распознаетпеременная user, как и должно быть.

Вместо этого, если я переместу инструкцию next() более внутренне:

var keystone = require('keystone');
var User = keystone.list('User');
var bcrypt = require('bcrypt');

exports = module.exports = function (req, res) {

    var view = new keystone.View(req, res);
    var locals = res.locals;
    var utente = req.body.utente;
    var passwd = req.body.password;

    // locals.section is used to set the currently selected
    // item in the header navigation.
    locals.section = 'home';

    view.on('init', function(next){
        next();
    });

    view.on('post', { action: 'signin' }, function (next) {
        // console.log("utente: " + utente);

        User.model.find()
            .where('email', utente)
            .exec()
            .then(function (user) { //first promise fulfilled
                //return another async promise

                console.log("user: ", user);
                console.log("email: ", user[0].email);
                console.log("password: ", user[0].password);

                bcrypt.compare(passwd, user[0].password, function(err, res) {
                    if(res){
                        console.log("Signin OK!");
                        locals.user = user[0];
                    }else{
                        console.log("Wrong Email or Password!");
                        req.flash("error", "wrong email or password!");
                    }
                    next();
                });

            }, function (err) { //something happened
                //catch the error, it can be thrown by any promise in the chain
                console.log(err);
                next();
            });

        //next();
    });

    // Render the view
    view.render('index');
};

Все идет хорошо! И переменная user читается правильно.

Как это возможно? В этих двух фрагментах кода позиция функции next() не эквивалентна ???

1 Ответ

0 голосов
/ 09 октября 2019

Они определенно не эквивалентны. У вас есть

        aPromise
            .then(function (user) { //first promise fulfilled
                bcrypt.compare(passwd, user[0].password, function(err, res) {/*...*/});

        next();

против

        aPromise
            .then(function (user) { //first promise fulfilled
                bcrypt.compare(passwd, user[0].password, function(err, res) {
                    /*...*/
                    next();
                });

В первом из них next() выполняется до выполнения обещания, сравниваются пароли, вызывается обратный вызов, и locals.user присваивается значение,В вашем втором он выполняется после всего того, что произошло.

...