繁体   English   中英

将参数传递给Javascript / NodeJ中的预定义回调

[英]Passing parameters to predefined callbacks in Javascript/NodeJs

我正在尝试使用bcrypt扩展NodeJs后端的简单登录方法。 我的问题是我现在需要通过哈希步骤传递user变量。 我当前的方法看起来像这样-并且自然在onPasswordHashed的范围内未定义user

signin : function(req, res, next) {
  step (
    function findUser() {
      User.findOne({ "email": req.body.email }, this);
    },
    function onResultReceived(error, user) {
      if (error) {
        ...
      } else {
        if (user) {
          bcrypt.compare(req.body.password, user.password, this);
        } else {
          ...
        }
      }     
    },
    function onPasswordHashed(error, hash) {
      if (error) {
        ...
      } else {
        bcrypt.compare(user.password, hash, this); // user is undefined here
      }
    },
    ...
  );
},

原则上,我可以:(a)使用bcrypt的同步调用。 但是,在某些时候,我可能会遇到相同的问题,即没有可用的同步函数。 (b)我可以首先定义var userObj = null ,然后在onResultReceived方法中将其设置为userObj = user 然后, userObj在所有作用域中都应可见。 但这似乎不是最佳实践。 还是呢?

到目前为止,使用bind()似乎是可行的方法。 我只是不了解如何将其应用于我。 例如:

bcrypt.compare(req.body.password, user.password, this.bind({user: user}));

不起作用。 我不知道step包是否会在这里引起任何问题。 处理回调链非常方便。

编辑:链接到step包文档: npmgithub

根据我发现和测试的内容,我可以覆盖回调,例如:

bcrypt.compare(req.body.password, user.password, this(user));

但是我当然会松散有关errorhash

您可以使用可以直接访问父级作用域中的变量的内联匿名回调,也可以使用.bind()将参数添加到回调中,或者在您的特定序列情况下,可以将user对象保存到范围更大的变量中它可用于后续回调。 请参localUser示例中的localUser变量:

signin : function(req, res, next) {
  var localUser;
  step (
    function findUser() {
      User.findOne({ "email": req.body.email }, this);
    },
    function onResultReceived(error, user) {
      // save user variable to higher scoped variable so
      // subsequent callbacks can access it
      localUser = user;
      if (error) {
        ...
      } else {
        if (user) {
          bcrypt.compare(req.body.password, user.password, this);
        } else {
          ...
        }
      }     
    },
    function onPasswordHashed(error, hash) {
      if (error) {
        ...
      } else {
        // use localUser from higher scope here that was set by a previous
        // step in the process
        bcrypt.compare(localUser.password, hash, this);
      }
    },
    ...
  );
},

仅供参考,如果您提供一些有关step()函数如何工作的信息或指向doc的链接,则也可能存在一种将数据从一个步骤传递到下一步骤的方法。


假设step()函数来自此模块 ,您也可以像这样进行操作:

signin : function(req, res, next) {
  step (
    function findUser() {
      User.findOne({ "email": req.body.email }, this);
    },
    function onResultReceived(error, user) {
      // save user on our stepper object so it can be accessed by later callbacks
      this.user = user;
      if (error) {
        ...
      } else {
        if (user) {
          bcrypt.compare(req.body.password, user.password, this);
        } else {
          ...
        }
      }     
    },
    function onPasswordHashed(error, hash) {
      if (error) {
        ...
      } else {
        // use this.user that was set by a previous
        // step in the process
        bcrypt.compare(this.user, hash, this);
      }
    },
    ...
  );
},

传递给每个后续回调的this值是一个公共函数对象,您可以将自己的属性附加到该对象。 虽然这种方法看起来比以前的版本干净,但实际上要危险一些,因为添加this对象的属性可能与step()函数的内部实现中使用的内容发生冲突。 第一个选项(父级作用域中的一个对象)是完全私有的,不会有任何可能的冲突。


现在了解了更多有关step()工作原理的信息之后,可以使用.bind()user对象添加到下一个回调参数中,如下所示:

signin : function(req, res, next) {
  step (
    function findUser() {
      User.findOne({ "email": req.body.email }, this);
    },
    function onResultReceived(error, user) {
      // save user on our stepper object so it can be accessed by later callbacks
      if (error) {
        ...
      } else {
        if (user) {
          // prepend user to the callback arguments for the next callback
          bcrypt.compare(req.body.password, user.password, this.bind(this, user));
        } else {
          ...
        }
      }     
    },
    function onPasswordHashed(user, error, hash) {
      // user is passed in here from previous callback
      if (error) {
        ...
      } else {
        // use this.user that was set by a previous
        // step in the process
        bcrypt.compare(user, hash, this);
      }
    },
    ...
  );
},

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM