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

时间:2021-02-28 16:48:24
  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();
      }
    });
  },

This function almost works properly, but the line:

这个功能几乎正常,但行:

        data.save();

runs before the previous line finishes which means that the data I want to save isn't present at the appropriate time.

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

        data.mongo_id = userCreationCtrl(account);

This line calls a function that creates a mongoDB document with information in the account object and then returns the _id (which is what I am trying to save.

这一行调用一个函数,该函数使用帐户对象中的信息创建一个mongoDB文档,然后返回_id(这就是我想要保存的内容)。

I thought maybe using a .then() would help but that seems to be unavailable here for some reason. If anyone sees something I'm missing, that would be quite helpful. Thank you!

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

Here is the userCreationCtrl file as requested:

这是请求的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;

1 个解决方案

#1


2  

You have userCreationCtrl expecting 3 arguments, account, res, and next. next is the callback that should be called after the user is created so instead of return result._id you should call next like so:

你有userCreationCtrl期待3个参数,帐户,res和下一个。接下来是应该在创建用户后调用的回调,而不是返回result._id,你应该调用next,如下所示:

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

then calling code in postRegistrationHandler should look like this:

然后在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();
    });
  }
});

#1


2  

You have userCreationCtrl expecting 3 arguments, account, res, and next. next is the callback that should be called after the user is created so instead of return result._id you should call next like so:

你有userCreationCtrl期待3个参数,帐户,res和下一个。接下来是应该在创建用户后调用的回调,而不是返回result._id,你应该调用next,如下所示:

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

then calling code in postRegistrationHandler should look like this:

然后在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();
    });
  }
});