jjzjj

javascript - meteor - 在返回之前同步多个异步查询?

coder 2024-07-15 原文

所以我有一个 Meteor 方法应该告诉服务器向 3rd 方 API 发送多个 API 请求,然后将这些查询的结果组合成一个数组,返回给客户端。

但是,我似乎找不到让服务器等到所有 API 查询完成后再返回结果的方法。

代码的同步版本,只是一个接一个地获取数据 API 调用,是这样的:

Meteor.methods({
    fetchData: function(APILinks) {
        var data = [];
        APILinks.forEach(function(APILink) {
            var items = HTTP.get(APILink).content.items;
            items.forEach(function (item) {
                data.push(item);
            });
        });
        return items;
    }
});

此同步代码有效。但是,我还没有找到使 API 请求异步的好方法。我最接近的解决方案是重新定义方法以仅返回一个 API 请求的结果,然后让客户端循环遍历每个 API 链接并为每个链接调用该方法。但是,有没有一种方法可以将所有这些请求包装到一个很好的方法中,该方法仅在所有 API 请求完成时返回?

最佳答案

您必须使用 HTTP.get 的异步版本并使用 Future 收集结果。

我编了一个简单的例子,使用 setTimeouts 来模拟 HTTP 请求,这样你就可以理解原理了,我建议你从这段代码开始,把虚拟的 setTimeout 替换成您的 HTTP 获取请求。

该示例是一个测试 服务器方法,它以多个任务 (n) 作为参数,然后启动 n 个任务,每个任务在索引秒内计算其索引的平方。

// we use fibers which is a dependency of Meteor anyway
var Future = Npm.require("fibers/future");

Meteor.methods({
    test: function(n) {
        // build a range of tasks from 0 to n-1
        var range = _.range(n);
        // iterate sequentially over the range to launch tasks
        var futures = _.map(range, function(index) {
            var future = new Future();
            console.log("launching task", index);
            // simulate an asynchronous HTTP request using a setTimeout
            Meteor.setTimeout(function() {
                // sometime in the future, return the square of the task index
                future.return(index * index);
            }, index * 1000);
            // accumulate asynchronously parallel tasks
            return future;
        });
        // iterate sequentially over the tasks to resolve them
        var results = _.map(futures, function(future, index) {
            // waiting until the future has return
            var result = future.wait();
            console.log("result from task", index, "is", result);
            // accumulate results
            return result;
        });
        //
        console.log(results);
        return results;
    }
});

在浏览器控制台中输入 > Meteor.call("test",3,function(error,result){console.log(result);});。这将在 3 秒后输出 [0,1,4]

在您的服务器控制台中,这将输出:

// immediately :
launching task 0
launching task 1
launching task 2
// after 1 second :
result from task 0 is 0
// after 2 seconds :
result from task 1 is 1
// after 3 seconds :
result from task 2 is 4
[ 0, 1, 4 ]

HTTP.get 异步版本在 Meteor 文档中有详细说明:

http://docs.meteor.com/#http_call

如果您想更好地理解整个 Future 概念,请参阅纤维文档:

https://github.com/laverdet/node-fibers

关于javascript - meteor - 在返回之前同步多个异步查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25940806/

有关javascript - meteor - 在返回之前同步多个异步查询?的更多相关文章

  1. ruby-on-rails - Rails 3 中的多个路由文件 - 2

    Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题

  2. ruby - ECONNRESET (Whois::ConnectionError) - 尝试在 Ruby 中查询 Whois 时出错 - 2

    我正在用Ruby编写一个简单的程序来检查域列表是否被占用。基本上它循环遍历列表,并使用以下函数进行检查。require'rubygems'require'whois'defcheck_domain(domain)c=Whois::Client.newc.query("google.com").available?end程序不断出错(即使我在google.com中进行硬编码),并打印以下消息。鉴于该程序非常简单,我已经没有什么想法了-有什么建议吗?/Library/Ruby/Gems/1.8/gems/whois-2.0.2/lib/whois/server/adapters/base.

  3. ruby-on-rails - 在 Ruby 中循环遍历多个数组 - 2

    我有多个ActiveRecord子类Item的实例数组,我需要根据最早的事件循环打印。在这种情况下,我需要打印付款和维护日期,如下所示:ItemAmaintenancerequiredin5daysItemBpaymentrequiredin6daysItemApaymentrequiredin7daysItemBmaintenancerequiredin8days我目前有两个查询,用于查找maintenance和payment项目(非排他性查询),并输出如下内容:paymentrequiredin...maintenancerequiredin...有什么方法可以改善上述(丑陋的)代

  4. ruby-on-rails - Rails - 一个 View 中的多个模型 - 2

    我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何

  5. ruby - 为什么 4.1%2 使用 Ruby 返回 0.0999999999999996?但是 4.2%2==0.2 - 2

    为什么4.1%2返回0.0999999999999996?但是4.2%2==0.2。 最佳答案 参见此处:WhatEveryProgrammerShouldKnowAboutFloating-PointArithmetic实数是无限的。计算机使用的位数有限(今天是32位、64位)。因此计算机进行的浮点运算不能代表所有的实数。0.1是这些数字之一。请注意,这不是与Ruby相关的问题,而是与所有编程语言相关的问题,因为它来自计算机表示实数的方式。 关于ruby-为什么4.1%2使用Ruby返

  6. ruby-on-rails - 如何在 ruby​​ 中使用两个参数异步运行 exe? - 2

    exe应该在我打开页面时运行。异步进程需要运行。有什么方法可以在ruby​​中使用两个参数异步运行exe吗?我已经尝试过ruby​​命令-system()、exec()但它正在等待过程完成。我需要用参数启动exe,无需等待进程完成是否有任何ruby​​gems会支持我的问题? 最佳答案 您可以使用Process.spawn和Process.wait2:pid=Process.spawn'your.exe','--option'#Later...pid,status=Process.wait2pid您的程序将作为解释器的子进程执行。除

  7. ruby - 多个属性的 update_column 方法 - 2

    我有一个具有一些属性的模型:attr1、attr2和attr3。我需要在不执行回调和验证的情况下更新此属性。我找到了update_column方法,但我想同时更新三个属性。我需要这样的东西:update_columns({attr1:val1,attr2:val2,attr3:val3})代替update_column(attr1,val1)update_column(attr2,val2)update_column(attr3,val3) 最佳答案 您可以使用update_columns(attr1:val1,attr2:val2

  8. ruby-on-rails - 在 ruby​​ .gemspec 文件中,如何指定依赖项的多个版本? - 2

    我正在尝试修改当前依赖于定义为activeresource的gem:s.add_dependency"activeresource","~>3.0"为了让gem与Rails4一起工作,我需要扩展依赖关系以与activeresource的版本3或4一起工作。我不想简单地添加以下内容,因为它可能会在以后引起问题:s.add_dependency"activeresource",">=3.0"有没有办法指定可接受版本的列表?~>3.0还是~>4.0? 最佳答案 根据thedocumentation,如果你想要3到4之间的所有版本,你可以这

  9. ruby-on-rails - 在 Rails 和 ActiveRecord 中查询时忽略某些字段 - 2

    我知道我可以指定某些字段来使用pluck查询数据库。ids=Item.where('due_at但是我想知道,是否有一种方法可以指定我想避免从数据库查询的某些字段。某种反拔?posts=Post.where(published:true).do_not_lookup(:enormous_field) 最佳答案 Model#attribute_names应该返回列/属性数组。您可以排除其中一些并传递给pluck或select方法。像这样:posts=Post.where(published:true).select(Post.attr

  10. ruby - 检查字符串是否包含散列中的任何键并返回它包含的键的值 - 2

    我有一个包含多个键的散列和一个字符串,该字符串不包含散列中的任何键或包含一个键。h={"k1"=>"v1","k2"=>"v2","k3"=>"v3"}s="thisisanexamplestringthatmightoccurwithakeysomewhereinthestringk1(withspecialcharacterslike(^&*$#@!^&&*))"检查s是否包含h中的任何键的最佳方法是什么,如果包含,则返回它包含的键的值?例如,对于上面的h和s的例子,输出应该是v1。编辑:只有字符串是用户定义的。哈希将始终相同。 最佳答案

随机推荐