在这种情况下需要对 Node.js 中的函数进行阻塞调用吗?

2023-12-01

我开始学习node.js。我在这里遇到了一个问题。我正在调用返回 JSON 的天气服务(网址如下)。

http://api.wunderground.com/api/Your_key/conditions/q/CA/San_Francisco.json

我想在 HTML 页面上显示 api 的结果。

我编写了以下代码(getInfo 模块)来检索并返回 JSON。

var fbResponse; 

module.exports = function (url) {

var http=require('http');


http.get(url, function(res) {
    var body = '';

    res.on('data', function(chunk) {
        body += chunk;
    });

    res.on('end', function() {
        fbResponse = JSON.parse(body);  
        console.log("Got response: ", fbResponse.response);


    });

}).on('error', function(e) {
      console.log("Got error: ", e);
});


return fbResponse;
};

因此,为了使用这个模块,我创建了一个 test.js 文件,如下所示:

var relay = require('./getInfo');
var url = 'http://api.wunderground.com/api/Your_key/conditions/q/CA/San_Francisco.json';
var response;
var x=relay(url);

console.log (x);

输出如下:

undefined                //  console.log(x) from test.js
Got response:  { version: '0.1',
  termsofService: 'http://www.wunderground.com/weather/api/d/terms.html',
  features: { conditions: 1 } }

测试代码中的控制台输出首先运行,其中没有数据。 HTTP get 稍后竞争并显示我需要的实际输出。

如何修改测试代码以进行阻塞调用,以便测试代码中的 var x 实际上具有 JSON 输出而不是未定义?

我可以在不阻塞调用 getInfo 模块的情况下获得所需的结果吗?


如您所知,节点是异步的,因此回调http.get and res.on('end', ..将在之后触发relay函数被执行并返回。所以通常你不能从中返回结果。

您有几个选择:

  • 将回调传递给relay并使用它:

    module.exports = function (url, cb) {
        http.get(url, function(res) {
    
            var body = '';
            res.on('data', function(chunk) {
                body += chunk;
            });
    
            res.on('end', function() {
                cb(null, JSON.parse(body));
            });
    
        }).on('error', cb);
    };
    

    然后像这样使用它:

    var relay = require('./getInfo');
    relay(url, function (err, x) {
        if (err) {
            console.error('oohh i got a error: ', err)    
        }
        console.log('oohh i got a response: ', x)    
    });
    
  • 使用承诺。这与传递回调几乎相同。稍微不那么轻量级,但是当组合不同的异步操作时,你就会明白它们有多么棒。对于一个异步调用来说可能没有任何区别。这里我使用q。您还可以使用bluebird它的性能更高,但缺乏 q 的一些糖分。你可以阅读本文理解为什么在某些情况下承诺比回调更干净。

    module.exports = function (url) {
        var deferred = Q.defer();
        http.get(url, function(res) {
            var body = '';
            res.on('data', function(chunk) {
                body += chunk;
            });
    
            res.on('end', function() {
                deferred.resolve(JSON.parse(body));
            });
    
        }).on('error', function(e) {
            deferred.reject(e);
        });
        return deferred.promise;
    };
    
    
    
    var relay = require('./getInfo');
    relay(url).then(function responseHandler(x) {
        console.log('my awesome response')
    }, function errorHandler(err) {
        console.error('got an error', err);
    });
    
  • 使用发电机。它是 Ecmascript 6 规范的一部分,仅存在于节点 v0.11.x 及更高版本中。但这几乎就是你想要的。

    通过过去的承诺示例,我们可以这样做:

    Q.async(function *() {
        var relay = require('./getInfo');
        var x = yield relay(url);
        console.log('my awesome response', x)
    });
    

    这几乎就是你想要的。您还可以使用回调解决方案来实现它co library:

    co(function *() {
        var relay = require('./getInfo');
        var x = yield relay.bind(null, url);
        console.log('my awesome response', x);
    });
    

    您还可以使用节点纤维在上面的例子中,它几乎是一个类似于生成器的工具。

    如果你想使用前沿的 Javascript,你可以使用异步/等待而不是有承诺的发电机。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在这种情况下需要对 Node.js 中的函数进行阻塞调用吗? 的相关文章

  • 如何动态删除嵌套的json键?

    这是示例 json search facets author language value nep count 3 value urd count 1 source value West Bengal State Council of Vo
  • 图表.js.如何更改“标签”数组的字体样式?

    我从 Chart JS 库中获取了一个图表 截屏 https i stack imgur com DnuRq png var ctx document getElementById myChart var data labels HTML
  • querySelector 搜索直接子级[重复]

    这个问题在这里已经有答案了 我有一些类似 jquery 的函数 function elem return gt someselector elem 问题是我怎样才能做同样的事情querySelector 问题是 gt 选择器中querySe
  • 如何正确地将节点从引用传递到上下文?

    我正在尝试将节点从引用传递到上下文 但是因为我在第一次渲染后没有重新渲染 所以传递的节 点是null 我考虑了两种变体 但我认为它们不是最好的 To pass ref代替ref current 但在用例中 我将被迫使用类似的东西contex
  • 从 puppeteer PDF 中删除分页符?

    我目前正在尝试查看是否有一种方法可以删除我的 puppeteer PDF 中的分页符 因为我当前的 PDF 设置中的一些分页符正在以一种奇怪的方式切断文本 我正在谈论的内容的屏幕截图 我的傀儡代码 app get companyId pdf
  • 为什么我可以使用 Date 对象进行数学运算? [复制]

    这个问题在这里已经有答案了 当我像这样减去两个日期对象时 const startTime new Date await someAsyncStuff const endTime new Date const elapsedTime endT
  • 早于 0.4.12 的 Node.js 无法在 AWS EC2 上正常工作。为什么?

    我无法在 AWS EC2 Ubuntu 或 CentOs 没关系 上安装 node js v0 6 1 安装后我输入node 处理器负载达到100 但 v0 4 12 工作正常 可能只有我有这个问题 那不好意思了 请告诉我我做错了什么 提前
  • 无需重定向的 HTML 页面提交

    有没有什么方法可以在不使用ajax的情况下提交html表单而无需从当前页面重定向 你可以设置一个target 为您form 这样您就可以将表单提交到新选项卡 target blank 或一个小的 隐藏的iframe target nameo
  • 仅从功能区打开一个对话框

    我有一个带有登录按钮的功能区 可打开登录对话框 我想将对话框的数量限制为一个 我正在使用函数 displayDialogAsync startAddress options callback https learn microsoft co
  • 如何使用 github 托管外部 CSS 文件?

    我将 css 上传到 github 然后转到网站上的文件并单击 raw 选项 我尝试将其添加到网页中 但 chrome 给出以下错误 资源解释为样式表 但使用 MIME 类型 text plain 进行传输 https raw github
  • 公开闭包内的方法

    当我们在闭包内创建一个方法时 该方法将成为该闭包的私有方法 并且在我们以某种方式公开它之前无法访问它 怎么可能暴露呢 您可以返回对它的引用 var a function var b function I m private alert go
  • 基于范围内变量的角度设置形式动作

    我一直在尝试设置一个搜索表单 可以在其中注入表单操作属性 在我的表格中我有
  • 文件缓存:查询字符串与上次修改时间?

    我正在研究缓存网站资源的方法 并注意到大多数与我类似的网站都使用查询字符串来覆盖缓存 例如 css style css v 124942823 后来 我注意到每当我保存 style css 文件时 最后修改的标头都会 更新 使得查询字符串变
  • 将默认搜索文本添加到搜索框 html

    我正在努力将 搜索 文本添加到搜索框 我正在努力实现 onfocus 消失文本 And onblur 重新出现文本 到目前为止 我已经实现了这一点 但我必须将其硬编码为 html eg
  • 在 Express.js 中使用相同的响应对象发送多个响应(res.json)

    res json Object assign cart generateArray res json JSON stringify cart totalPrice 我如何发送发送多个响应 因为我的代码不起作用 谢谢 您不能发送多个回复 您发
  • D3 强制布局,较大的节点聚集在中心

    我一直在修改将用于标签云的强制布局 每个标签都由一个
  • eventSources 到事件 Json,完整日历

    我正在尝试从 eventSources 获取 json 调用到我的事件 我在 eventSources 中返回的 json 是 title Title Test start 1305841052 当我将此字符串传递到事件中时 它会正确显示日
  • 如何得知客户端从服务器的下载速度?

    根据客户的下载速度 我想以低质量或高质量显示视频 任何 Javascript 或 C 解决方案都是可以接受的 Thanks 没有任何办法可以确定 您只能测量向客户端发送数据的速度 如果没有来自客户端的任何类型的输入来表明其获取信息的速度 您
  • 在引导程序中以编程方式更改选项卡窗格选项卡

    我使用的选项卡窗格定义为 ul class nav nav tabs li a href personal Personal Information a li li class active a href contact Contact a
  • jQuery appendTo(), json 在 IE 6,7,8 中不起作用

    我这两天绞尽脑汁想找到解决办法 我使用 jQuery ajax 从数据库中获取值 以便在另一个框发生更改时更新一个框 php 脚本从数据库中获取值 然后输出 json 它在 FF 中工作正常 但在所有版本的 IE 中 选择框都不会更新 我已

随机推荐