在nodes.js中跨函数和javascript文件隐式传递上下文

时间:2017-05-15 19:16:26

标签: javascript node.js express passport.js

我使用快递和护照创建了一个web服务器i node.js。它使用oauth 2.0策略(https://www.npmjs.com/package/passport-canvas)进行身份验证。经过身份验证后,我想拨打电话,例如:

app.get("/api/courses/:courseId", function(req, res) {
  // pass req.user.accessToken implicitly like 
  // through an IIFE
  createExcelToResponseStream(req.params.courseId, res).catch(err => {
    console.log(err);
    res.status(500).send("Ops!");
  });
});

我的问题是,我想在createExcelToResponseStream的所有后续调用中访问我的accessToken。我需要在我的业务层中稍后进行大量的api调用。我将调用一个看起来像这样的方法:

const rq = require("request");    
const request = url => {
  return new Promise(resolve => {
    rq.get(
      url,
      {
        auth: {
          bearer: CANVASTOKEN // should be req.user.accessToken 
        }
      },
      (error, response) => {
        if (error) {
          throw new Error(error);
        }
        resolve(response);
      }
    );
  });
};
  • 如果我尝试创建访问令牌的全局访问权限,我将面临风险 竞争条件(我认为) - 即人们在另一个人访问令牌的上下文中获得响应。
  • 如果我将上下文作为变量传递,我必须重构a 我的代码库和许多业务层功能必须要有 了解他们不需要知道的事情

在javascript中有什么方法我可以通过整个callstack传递上下文,跨函数,模块和文件(通过scope,apply,bind,this ...)。有点像在多线程环境中可以执行的操作,每个线程都有一个用户上下文。

2 个答案:

答案 0 :(得分:0)

你唯一能做的就是

.bind(req);

但是必须将其链接到每个内部函数调用

somefunc.call(this);

或者您只使用内联箭头功能

 (function (){
   inner=()=>alert(this);
   inner();
 }).bind("Hi!")();

或者,您可以将所有函数应用于Object,然后创建一个新实例:

var reqAuthFunctions={
  example:()=>alert(this.accessToken),
  accessToken:null
};

instance=Object.assign(Object.create(reqAuthFunctions),{accessToken:1234});
instance.example();

答案 1 :(得分:0)

你可以使用Promise来避免Race条件。 我们有这个模块:

// ContextStorage.js
let gotContext;
let failedGettingContext;
const getContext = new Promise((resolve,reject)=>{
  gotContext = resolve;
  failedGettingContext = reject;
}
export {getContext,gotContext, failedGettingContext};

这个启动:

// init.js
import {gotContext} from './ContextStorage';
fetch(context).then(contextIGot => gotContext(contextIGot));

这件事需要上下文:

// contextNeeded.js
import {getContext} from './ContextStorage';
getContext.then(context => {
  // Do stuff with context
}

这显然不是非常有用的代码,因为它都是在加载时执行的,但我希望它为你提供了一个如何用门户来思考这个问题的框架......我的意思是Promises ......

当您调用导入的'gotContext'时发生的事情,您实际上解决了'getContext'返回的承诺。因此,无论操作顺序如何,您都可以在请求上下文后解析promise,将依赖操作设置为motion,或者您的singleton已经解析了promise,并且依赖操作将同步继续。

另一方面,您可以轻松地在“ContextStorage”单例中获取promise中“body”中的上下文。然而,这不是很模块化,现在就是它。一种更好的方法是将初始化函数注入单例中以反转控制,但这会使代码混淆一些我觉得阻碍演示的目的。