Node.js Q承诺然后()链接不等待

Fra*_*ela 3 javascript node.js promise q

我试图重构以下代码,以避免回调地狱,将其转换为:

createUser(user_data)
  .then(createClient(client_data))
  .then(createClientPartner(clientpartner_data))
  .then(function(data) {
    cb(null, _.pick(data,['id','username']));
  }, function(error) {
    cb(error);
  });
Run Code Online (Sandbox Code Playgroud)

如您所见,我为每个步骤创建了一个方法:

function createUser(user_data) {
  console.log('createUser');
  var deferred = Q.defer()

  new db.models.User.create(user_data, function(err, user) {
    console.log('createUser done');
    if (!!err)
      deferred.reject(err);
    else {
      client_data['id'] = user.id;
      deferred.resolve(user);
    }
  });

  return deferred.promise;
}
Run Code Online (Sandbox Code Playgroud)

其他方法具有相同的console.log调用,以便能够遵循执行路径.

我希望它是:

  • 创建用户
  • createUser完成了
  • createClient
  • createClient完成了
  • createClientPartner
  • createClientPartner完成了

但相反,它是:

  • 创建用户
  • createClient
  • createClientPartner
  • createClientPartner完成了
  • createUser完成了
  • createClient完成了

为什么在前一个承诺尚未解决时触发了功能?我希望"然后"等到先前的承诺得到解决或拒绝继续.我错过了一些重要的承诺吗?

Den*_*ret 5

问题是你不传递函数,而是函数调用的结果.

代替

createUser(user_data)
  .then(createClient(client_data))
Run Code Online (Sandbox Code Playgroud)

你应该有

createUser(user_data)
.then(function(user){
    createClient(client_data) // no need for the user ? really ?
})
Run Code Online (Sandbox Code Playgroud)