2017-03-09 278 views
0

我想編寫一個從API請求令牌的應用程序。只要此令牌不可用,我不想繼續使用其他應用程序。所以它必須像一個同步的HTTP請求。NodeJS等待HTTP請求

我的目標是創建一個執行請求的功能,然後返回令牌,如:

var token=getToken(); //After this function has finished 
makeRequest(token); //I want this function to be executed 

我怎樣才能做到這一點?

回答

2

它根本不想同步。擁抱回調的力量:

function getToken(callback) { 
    //get the token here 
    callback(token); 
}; 

getToken(function(token){ 
    makeRequest(token); 
}); 

這可確保在getToken完成之後才執行makeRequest。

+0

所以這意味着在回調函數中我的整個代碼都必須執行? –

+0

@Chaos_:是的,就像異步代碼一樣(語法糖像'await'儘管)。 –

+0

如果你想。它有助於模塊化執行不同任務的功能,因爲您可能再次使用它們,因此不應重複自己。如果您之前使用過其他同步語言,比如PHP,那麼新的語法風格可能需要一些習慣。只記得在你的第一個例子中,var token是未定義的,直到getToken()完成並且makeRequest將立即執行,有或沒有(最有可能沒有)getToken完成。 – Taintedmedialtd

3

我的目標是創建一個執行請求的功能,然後返回令牌

您不能返回一個值,它不會立即有一個函數。你只能回報一個承諾。

然後在代碼的其他部分,你可以等待承諾使用再處理來實現,也可以使用類似:

var token = await getToken(); 

內的async function來等待值可用,但前提是getToken()函數返回承諾。

例如,使用request-promise模塊它會是這樣的:

var rp = require('request-promise'); 
function getToken() { 
    // this returns a promise: 
    return rp('http://www.example.com/some/path'); 
}) 

然後其他一些功能:

function otherFunction() { 
    getToken().then(token => { 
     // you have your token here 
    }).catch(err => { 
     // you have some error 
    }); 
} 

或者,用async function是這樣的:

async function someFunction() { 
    try { 
     var token = await getToken(); 
     // you have your token here 
    } catch (err) { 
     // you have some error 
    } 
} 

參見:https://www.npmjs.com/package/request-promise

請注意,async functionawait是在ECMAScript 2017草案(ECMA-262)中定義的,截至2017年3月(編寫時間爲2017年6月)本文撰寫之時,該草案尚未完成。

但自v7.6以來,它已經在Node中可用(如果使用--harmony標誌,它在v7.0以後可用)。對於節點版本的兼容性,請參閱:

如果你想爲老年人節點版本略有不同的語法類似的功能,你可以使用的模塊,比如coPromise.coroutineBluebird

0

您可以使用JavaScript Promise或承諾圖書館像async

由JavaScript承諾:

new Promise((resolve, reject) => { 
    resolve(getToken()); 
}).then(token =>{ 
    //do you rest of the work 
    makeRequest(token); 
}).catch(err =>{ 
    console.error(err) 
}) 
0

可以使用ES6的特性稱爲發電機。您可以按照此article瞭解更深層次的概念。但基本上你可以使用生成器和承諾來完成這項工作。我使用bluebird來promisify和管理生成器。

你的代碼應該像下面的例子一樣好。

const Promise = require('bluebird'); 

function getToken(){ 
    return new Promise(resolve=>{ 
      //Do request do get the token, then call resolve(token). 
     }) 
} 

function makeRequest(token){ 
    return new Promise(resolve=>{ 
    //Do request do get whatever you whant passing the token, then call resolve(result). 
    }) 
} 

function* doAsyncLikeSync(){ 
    const token= yield getToken(); //After this function has finished 
    const result = yield makeRequest(token); //I want this function to be executed 
    return result; 
} 

Promise.coroutine(doAsyncLikeSync)() 
    .then(result => { 
    //Do something with the result 
    })