2017-05-15 13 views
0

我已經使用express和passport創建了一個web服務器node.js。它使用oauth 2.0策略進行身份驗證(https://www.npmjs.com/package/passport-canvas)。當鑑定,我想打個電話,如:通過contexts.js中的函數和JavaScript文件隱式傳遞上下文

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); 
     } 
    ); 
    }); 
}; 
  • 如果我嘗試創建到訪問令牌的全局訪問,我將風險 競爭條件(我認爲) - 即人們得到的答覆另一個人訪問令牌的上下文。
  • 如果我通過上下文作爲一個變量,我必須修改我的代碼庫的 LOF和大量的業務層功能必須 瞭解一些他們並不需要了解

是有任何方式在JavaScript中,我可以通過上下文,跨功能,模塊和文件,通過整個調用堆棧(通過範圍,應用,綁定,這...)。有點像你在多線程環境中可以做到的,每個線程有一個用戶上下文。

+0

向createExcelToResponseStream添加第二個參數? (對不起,沒有其他方式,JS有詞法範圍) –

+0

我發現了一個框架,旨在做我想做的事:continuation-local-storage [link](https://www.npmjs.com/package/continuation-local-存儲)。但是我遇到了一些設計問題,因爲我只能從存儲中檢索一次該值。我需要多次訪問該值,除非我做了其他重構......我最終使用了第二個參數方法。不是很漂亮,但我100%確定我沒有比賽條件。 –

回答

0

,你唯一能做的事情將是

.bind(req); 

但是,已經有要鏈接到每一個內部函數調用

somefunc.call(this); 

您也可以使用內嵌箭頭功能僅

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

或者,您可以將所有函數應用到對象上,然後創建一個新的實例:

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

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

您可以使用Promise來避免競爭條件。 讓我們這個模塊:

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

這inititalization:

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

這件事,需要上下文:

​​

這顯然不是非常有用的代碼,因爲這一切負載執行,但我希望它給你一個如何考慮與門戶網站這個問題的框架...我的意思是諾言...

當您調用導入的'gotContext'時發生的事情,您實際上解決了由'getContext'返回的承諾。因此,無論操作順序如何,在請求上下文之後解決承諾,將相關操作設置爲運動,或者您的單例已經解決了承諾,並且相關操作將同步繼續。

另一方面,您可以很容易地在'ContextStorage'單例中的承諾的'body'中獲取上下文。然而,這不是很模塊化,現在就是這樣。一個更好的方法是將初始化函數注入單例中,以便反轉控制,但這會混淆代碼,這有點妨礙了演示的目的。

相關問題