NodeJS是asynchronous的,我的代码不按我期望的顺序运行

postRegistrationHandler: function (account, req, res, next) { console.log('postRegistrationHandler activated'); account.getCustomData(function(err, data) { if (err) { console.log(err.toString, "error string"); return next(err); } else { data.mongo_id = userCreationCtrl(account); data.save(); next(); } }); }, 

这个function几乎可以正常工作,但行:

  data.save(); 

在前一行完成之前运行,这意味着我想要保存的数据在适当的时候不存在。

  data.mongo_id = userCreationCtrl(account); 

这一行调用一个函数,它创build一个包含帐户对象中的信息的mongoDB文档,然后返回_id(这就是我正在保存的内容。

我想也许使用一个.then()会有所帮助,但由于某种原因,这似乎是不可用的。 如果有人看到我错过的东西,那将是相当有帮助的。 谢谢!

这里是请求的userCreationCtrl文件:

 var UserSchema = require('./../models/UserModel.js'); var createNewUser = function (account, res, next){ // We will return mongoId after it is created by submitting a newUser var mongoId = ""; // Save StormpathID (last 22 characters of account.href property) var newStormpathId = account.href.slice(account.href.length - 22); console.log('stormpath ID:', newStormpathId, 'just registered!'); console.log(account); // Create new user from model by recycling info from the Stormpath registration form and include the stormpathId as well. var newUser = new UserSchema({ stormpathId: newStormpathId, firstName: account.givenName, lastName: account.surname, email: account.email, street: account.street, city: account.city, zip: account.zip }); // This saves the user we just created in MongoDB newUser.save(function(err, result){ console.log(result); if (err) { console.error(err); } else { console.log("User created in MongoDB, attempting to return mongoDB _id to stormpath customData"); // Keep track of the new user's mongo _id so we can return it to the previous function and save it as Stormpath custom data. mongoId = result._id; console.log(mongoId, "mongoid"); return result._id; } }); }; module.exports = createNewUser; 

你有userCreationCtrl 3个参数, accountresnextnext是在创build用户之后应该调用的callback函数,而不是return result._id ,接下来应该这样调用:

 // inside of createNewUser() newUser.save(function(err, result){ console.log(result); if (err) { console.error(err); } else { console.log("User created in MongoDB, attempting to return mongoDB _id to stormpath customData"); // Keep track of the new user's mongo _id so we can return it to the previous function and save it as Stormpath custom data. mongoId = result._id; console.log(mongoId, "mongoid"); // IMPORTANT change to make it all work... // get rid of return result._id because its not doing anything // pass the value to your callback function instead of returning the value next(null, result._id); } }); 

那么在postRegistrationHandler调用代码应该看起来像这样:

 account.getCustomData(function(err, data) { if (err) { console.log(err.toString, "error string"); return next(err); } else { // pass in a callback as the 3rd parameter that will be called by newUser.save() when its finished userCreationCtrl(account, null, function(err, resultId) { data.save(); next(); }); } });