2017-03-09 274 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 
    })