Функция beforeCreate не выполняется последовательно

После обновления моих парусов (0.10-rc5),

Я столкнулся с проблемой в функции beforeCreate:

  beforeCreate : function(values, next){

      console.log("Called beforeCreate User ");
      console.log(values);

      if(!values.password || values.password !== values.confirmation){
          return next({
              err : ["Password doesn't match password confirmation"]
          });
      }

      bcrypt.genSalt(10, function(err, salt){
        console.log("call within bcrypt");
          if (err) return next(err);
           bcrypt.hash(values.password, salt, function(err, hash){
              if(err) return next(err);
               values.password = hash;
           });
      });

      Access.findOne()
          .where({ level : values.level })
          .exec(function(err, level){
            console.log("call within findOne");
              if(err) return next(err);
              values.level = level.id;
      });

      console.log("after");    
      console.log(values);
      next();
  } 

Однако вывод вышеуказанной функции выглядит следующим образом:

Called beforeCreate User 
{ firstName: 'Quad',
  lastName: 'Doe',
  email: '[email protected]',
  password: '123456',
  confirmation: '123456',
  level: 'admin',
  id: '2fa1ba1a-ae1c-4380-9107-3c1f6e8eafb3',
  online: false }
after
{ firstName: 'Quad',
  lastName: 'Doe',
  email: '[email protected]',
  password: '123456',
  confirmation: '123456',
  level: 'admin',
  id: '2fa1ba1a-ae1c-4380-9107-3c1f6e8eafb3',
  online: false }
call within bcrypt
call within findOne

Как видите, каким-то образом bcrypt.genSalt(.....){} и Access.findOne(...){} не были вызваны до после, как это и предполагалось.


person tebesfinwo    schedule 05.05.2014    source источник


Ответы (1)


То, что вы видите, это асинхронный код в действии...

Node/Sails не ждет, пока сработают ваши обратные вызовы, прежде чем перейти к следующей задаче.

Вам нужно «вложить» свои обратные вызовы, чтобы console.log("AFTER") вызывался в последнем обратном вызове.

Взгляните на async. Он предназначен для таких проблем.

Or...

Изучите волокна.

person InternalFX    schedule 05.05.2014
comment
Означает ли это, что он может вызвать самый конец next() и выйти из функции до окончания других функций внутри себя? - person tebesfinwo; 06.05.2014
comment
В яблочко. Ты сделал это. Если вы привыкли к синхронному программированию, поначалу это может показаться запутанным. Волокна действительно хороши для того, чтобы заставить узел чувствовать себя синхронным. - person InternalFX; 06.05.2014
comment
Спасибо @InternalFX. До этого функции внутри beforeCreate работали нормально (выполнялись до вызова следующего) в Sails 0.9v, я догадался, что они изменились. - person tebesfinwo; 06.05.2014
comment
@tebesfinwo Это довольно удивительно ... Асинхронная природа встроена в самое ядро ​​nodejs. Я бы порекомендовал одну из вышеперечисленных библиотек. Даже если это работало раньше, скорее всего, под поверхностью скрывалась неприятная ошибка / состояние гонки. Если вы явно не контролируете поток функций, кто знает, насколько плохо это может обернуться. - person InternalFX; 06.05.2014
comment
Верно. Хорошо, я сделаю. Еще раз спасибо. - person tebesfinwo; 06.05.2014