【问题标题】:NodeJS wait for HTTP requestNodeJS 等待 HTTP 请求
【发布时间】:2017-07-30 19:08:51
【问题描述】:

我想编写一个从 API 请求令牌的应用程序。只要此令牌不可用,我就不想继续应用程序的其余部分。所以它必须像一个同步的 HTTP 请求。

我的目标是创建一个执行请求然后返回令牌的函数,例如:

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

我该怎么做?

【问题讨论】:

标签: javascript node.js asynchronous https request


【解决方案1】:

它根本不想同步。拥抱回调的力量:

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

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

这确保在 getToken 完成之前不会执行 makeRequest。

【讨论】:

  • 所以这意味着在回调函数中我的整个代码必须被执行?
  • @Chaos_:是的,异步代码总是如此(尽管有 await 这样的语法糖)。
  • 如果你愿意。它有助于模块化执行不同任务的函数,因为您可能会再次使用它们并且您不应该重复自己。如果您之前使用过其他同步语言,例如 PHP,那么新的语法风格可能需要一些时间来适应。请记住,在您的第一个示例中,在 getToken() 完成之前,var token 是未定义的,并且 makeRequest 将立即执行,无论是否(很可能没有)getToken 完成。
  • 你不知道这个答案有多棒。网络上的所有其他解释都如此宏大和令人困惑。这很简单,而且非常有帮助。如果我可以投票两次,我会的。谢谢!
【解决方案2】:

我的目标是创建一个执行请求然后返回令牌的函数

你不能创建一个函数来返回一个它没有立即返回的值。你只能返回一个承诺。

然后在代码的其他部分中,您可以使用 then 处理程序等待 promise 完成,也可以使用类似:

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 月)。

但它已经在 Node v7.6 中可用(如果你使用 --harmony 标志,它从 v7.0 开始可用)。与 Node 版本的兼容性见:

如果您希望旧 Node 版本具有类似的功能,但语法略有不同,您可以使用 Bluebird 中的 coPromise.coroutine 等模块。

【解决方案3】:

您可以使用 javascript Promise 或 Promise 库,例如 async

通过 JavaScript 承诺:

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

【讨论】:

    【解决方案4】:

    您可以使用 ES6 的生成器功能。您可以关注article 以获得更深入的概念。但基本上你可以使用生成器和承诺来完成这项工作。我正在使用bluebird 来承诺和管理生成器。

    您的代码应该没问题,如下例所示。

    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
      })
    

    【讨论】:

      猜你喜欢
      • 2018-11-13
      • 1970-01-01
      • 1970-01-01
      • 2019-01-08
      • 2017-11-24
      • 2018-11-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多