草庐IT

multithreading - node.js模块: Async vs Fibers. Promise与Q_oper8

coder 2023-05-28 原文

只是想知道是否有人可以在处理异步事件的这些模块之间进行权衡比较。具体来说,我有兴趣了解使用异步而不是Fibers.promise的原因,至少现在我在测试代码中广泛使用了它。特别是,我在Fibers.promise中看到的主要优点之一是,我可以保持堆栈链的前端 fork ,从而可以使用try { } catch { } finally,并且还允许我确保在处理完请求后,响应结束。

有人在使用Q_oper8吗?我在另一页上找到了它,只是想知道那是已经死了还是应该检查一下。

最佳答案

我从未听说过Q_oper8,所以我无法对此发表评论,但是我将从另一个方向对此进行论述。我首先听说过异步,其次听说了Fiber(及其辅助程序库),实际上,我不喜欢后者。

纤维的缺点

其他Javascript开发人员不熟悉

Fiber通过已编译的Fiber native 方法将共例程的概念引入Javascript,该方法继承了传递给它的Javascript代码的解释,拦截对yield的调用以跳回到等待的协程。

这对您可能并不重要,但是如果您需要在团队中工作,则必须向您的成员讲授该概念(或者希望他们从其他语言(例如Go)中获得有关该概念的经验)。

没有Windows支持

因此,为了使用Fiber或在它上面编写的任何库,您必须首先为平台本地编译它。我不使用Windows,但是请注意Windows不支持Fiber,因此会限制您自己的库的实用性。这意味着您根本不会找到用Fiber编写的通用Node.js库(无论如何,您可能根本不会拥有,因为它增加了一个昂贵的编译步骤,否则您会避免使用异步方法)。

浏览器不兼容

这意味着您使用Fiber编写的任何代码都将无法在浏览器中运行,因为您无法将 native 代码与浏览器混合(我也不希望浏览器用户希望这样做),即使您编写的所有内容都是“Javascript ”(从语法上来说是Javascript,但从语义上来说则不是)。

更困难的调试

尽管“回调 hell ”在视觉上可能不太令人满意,但是“连续传递样式”确实比Co-Routines有一件非常好的事情-您确切地知道了调用堆栈中发生了问题的地方,并且可以向后追溯。协同例程在程序中的多个点上进入函数,并且可以从三种调用中退出:returnthrowyield(),后者也是返回点。

使用协同例程,您可以在“同时”运行的两个或多个函数之间执行交叉执行,并且事件循环上可能同时运行着多个协同例程。使用传统的回调,可以确保在执行该函数期间该函数的外部范围是静态的,因此仅在需要时检查这些外部变量一次。协同例程需要在每个yield()之后运行这些检查(因为它与原始协同例程的用法将转换为真实Javascript中的回调链)。

基本上,我认为使用协同例程的概念变得更加困难,因为它必须存在于Javascript事件循环内部,而不是作为一种实现方法。

是什么让Async变得“更好”?

越差越好

实际上,这是一种“更糟更好”的想法。 Async是一种纯Javascript解决方案,可以像化妆一样掩盖它们,而不是扩展Java语言以尝试消除其疣(并创建新的疣)。

控制流明确

异步函数描述了需要跨越事件循环障碍的不同类型的逻辑流,并且该库涵盖了实现该逻辑所需的回调代码的实现细节,您只需提供它的功能即可大致按线性顺序运行它们将在整个事件循环中执行。

如果您愿意在异步方法的参数周围放弃第一个缩进级别,则与协程相比没有多余的缩进,并且function(callback) {声明中只有很少的额外行,如下所示:

var async = require('async');
var someArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];
async.forEach(someArray,
function(number, callback) {
    //Do something with the number
    callback();
}, function(err) {
    //Done doing stuff, or one of the calls to the previous function returned an error I need to deal with
});

在这种情况下,您知道您的代码使用的所有变量只有在您的代码未更改的情况下才可以在运行代码之前进行更改,因此您可以更轻松地进行调试,并且只有一种“返回”机制:callback()您可以成功进行任何回调,也可以在出现问题时将错误传递给回调。

代码重用并不困难

上面的示例使代码重用变得困难,但这不是必须的。您始终可以将命名函数作为参数传递:
var async = require('async');

// Javascript doesn't care about declaration order within a scope,
// so order the declarations in a way that's most readable to you

async.forEach(someArray, frazzleNumber, doneFrazzling);

var someArray = [1, 2, 3, 4, 5, 6, 7, 8, 9];

function frazzleNumber(number, callback) {
    // Do something to number
    callback();
}

function doneFrazzling(err) {
    // Do something or handle error
}

功能性,非强制性

异步模块不鼓励使用命令式流控制,并鼓励(需要跨越事件循环的部分)使用功能进行流控制。

函数样式的优点在于,您可以轻松地重用循环主体或条件主体,并且可以创建新的控制流“动词”,以更好地匹配代码流(由异步库),例如async.auto控制流方法,该方法实现了函数调用顺序的依赖关系图解析。 (您指定了一系列命名函数,并列出了它要执行的其他函数(如果有的话),并且auto首先运行“独立”函数,然后运行下一个可以根据其相关函数完成运行的时间运行的函数。 )

而不是按照您的语言所规定的命令式风格来编写代码,而是按照问题的逻辑性来编写代码,并实现“胶水”控制流以使其得以实现。

总之

Fiber具有扩展Javascript语言的本质,因此无法在Node.js中开发大型生态系统,尤其是当Async在外观部门占据80%的份额,并且在Java协同例程中没有其他缺点时。

关于multithreading - node.js模块: Async vs Fibers. Promise与Q_oper8,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10282828/

有关multithreading - node.js模块: Async vs Fibers. Promise与Q_oper8的更多相关文章

  1. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  2. ruby-on-rails - Ruby net/ldap 模块中的内存泄漏 - 2

    作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代

  3. ruby-on-rails - 在混合/模块中覆盖模型的属性访问器 - 2

    我有一个包含模块的模型。我想在模块中覆盖模型的访问器方法。例如:classBlah这显然行不通。有什么想法可以实现吗? 最佳答案 您的代码看起来是正确的。我们正在毫无困难地使用这个确切的模式。如果我没记错的话,Rails使用#method_missing作为属性setter,因此您的模块将优先,阻止ActiveRecord的setter。如果您正在使用ActiveSupport::Concern(参见thisblogpost),那么您的实例方法需要进入一个特殊的模块:classBlah

  4. ruby - 当使用::指定模块时,为什么 Ruby 不在更高范围内查找类? - 2

    我刚刚被困在这个问题上一段时间了。以这个基地为例:moduleTopclassTestendmoduleFooendend稍后,我可以通过这样做在Foo中定义扩展Test的类:moduleTopmoduleFooclassSomeTest但是,如果我尝试通过使用::指定模块来最小化缩进:moduleTop::FooclassFailure这失败了:NameError:uninitializedconstantTop::Foo::Test这是一个错误,还是仅仅是Ruby解析变量名的方式的逻辑结果? 最佳答案 Isthisabug,or

  5. ruby - 获取模块中定义的所有常量的值 - 2

    我想获取模块中定义的所有常量的值:moduleLettersA='apple'.freezeB='boy'.freezeendconstants给了我常量的名字:Letters.constants(false)#=>[:A,:B]如何获取它们的值的数组,即["apple","boy"]? 最佳答案 为了做到这一点,请使用mapLetters.constants(false).map&Letters.method(:const_get)这将返回["a","b"]第二种方式:Letters.constants(false).map{|c

  6. ruby - 模块嵌套代码风格偏好 - 2

    我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的

  7. ruby-on-rails - 使用 config.threadsafe 时从 lib/加载模块/类的正确方法是什么!选项? - 2

    我一直致力于让我们的Rails2.3.8应用程序在JRuby下正确运行。一切正常,直到我启用config.threadsafe!以实现JRuby提供的并发性。这导致lib/中的模块和类不再自动加载。使用config.threadsafe!启用:$rubyscript/runner-eproduction'pSim::Sim200Provisioner'/Users/amchale/.rvm/gems/jruby-1.5.1@web-services/gems/activesupport-2.3.8/lib/active_support/dependencies.rb:105:in`co

  8. ruby-on-rails - Controller 中的 Rails 辅助模块 - 2

    我有一个Controller,我想为这个Controller创建一个助手,我可以在不包含它的情况下使用它。我尝试像这样创建一个与Controller同名的助手classCars::EnginesController我创建的助手是moduleCars::EnginesHelperdefcheck_fuellogger.debug("chekingfuel")endend我得到的错误是undefinedlocalvariableormethod`check_fuel'for#有没有我遗漏的约定? 最佳答案 如果你真的想在Controll

  9. ruby-on-rails - 具有同名的模块和类 - 2

    我有一个模块stat存在于目录结构中:lib/stat_creator/stat/在lib/stat_creator/stat.rb中,我在lib/stat_creator/stat/目录中有我需要的文件,以及:moduleStatCreatormoduleStatendend当我使用该模块时,我将这些类称为StatCreator::Stat::Foo.new现在我想要一个存在于应用程序中的根Stat类。我在app/models中制作了我的Stat类,并在routes.rb中进行了设置。但是,如果我转到Rails控制台并尝试在应用程序/模型中使用Stat类,例如:Stat.by_use

  10. ruby-on-rails - 使用 rspec 和 rails 测试嵌套模块 - 2

    这个问题在这里已经有了答案:关闭10年前。PossibleDuplicate:Testingmodulesinrspec目前我正在使用rspec成功测试我的模块,如下所示:require'spec_helper'moduleServicesmoduleAppServicedescribeAppServicedodescribe"authenticate"doit"shouldauthenticatetheuser"dopending"authenticatetheuser"endendendendend我的模块位于应用程序/服务/services.rb应用程序/服务/app_servi

随机推荐