Questions tagged «asynchronous-programming»

1
回调和Promises之间真的有根本的区别吗?
在执行单线程异步编程时,我熟悉两种主要技术。最常见的一种是使用回调。这意味着将传递给异步操作的函数的回调函数作为参数。当异步操作完成时,将调用回调。 jQuery这样设计一些典型的代码: $.get('userDetails', {'name': 'joe'}, function(data) { $('#userAge').text(data.age); }); 但是,当我们要在前一个完成后一个接一个地进行其他异步调用时,这种类型的代码可能会变得混乱且高度嵌套。 因此,第二种方法是使用Promises。Promise是一个对象,它表示可能不存在的值。您可以在其上设置回调,当准备读取值时将调用该回调。 Promises和传统的回调方法之间的区别在于,异步方法现在可以同步返回Promise对象,客户端将在其上设置回调。例如,在AngularJS中使用Promises的类似代码: $http.get('userDetails', {'name': 'joe'}) .then(function(response) { $('#userAge').text(response.age); }); 所以我的问题是:实际上有真正的区别吗?区别似乎纯粹是语法上的。 是否有更深层次的理由使用一种技术而不是另一种技术?


13
为什么编程语言不能自动管理同步/异步问题?
我没有找到很多有关此的资源:我想知道是否有可能/以同步方式编写异步代码的好主意。 例如,下面是一些JavaScript代码,该代码检索数据库中存储的用户数(异步操作): getNbOfUsers(function (nbOfUsers) { console.log(nbOfUsers) }); 能写这样的东西会很好: const nbOfUsers = getNbOfUsers(); console.log(getNbOfUsers); 因此,编译器将自动处理等待响应的内容,然后执行 console.log。在必须将结果用于其他任何地方之前,它将始终等待异步操作完成。我们将减少回调承诺,异步/等待或其他方法的使用,并且不必担心操作结果是否立即可用。 nbOfUsers使用try / catch或类似Swift中的可选参数仍然可以管理错误(得到整数还是错误?)语言。 可能吗?这可能是一个可怕的主意/乌托邦……我不知道。

4
是什么决定哪些Javascript函数正在阻塞与非阻塞?
几年来,我一直在做基于Web的Javascript(香草JS,jQuery,Backbone等),最近我正在与Node.js做一些工作。我花了一段时间才能摆脱“非阻塞”编程的束缚,但是我现在已经习惯于将回调用于IO操作等等。 我了解Javascript本质上是单线程的。我了解节点“事件队列”的概念。我不明白是什么决定了单个javascript操作是“阻止”还是“非阻止”。我如何知道我可以依靠哪些操作来同步生成输出供我在以后的代码中使用,以及我需要将哪些回调传递给我以便在初始操作完成后处理输出?在某个地方是否存在异步/非阻塞的Javascript函数列表,以及同步/阻塞的Javascript函数列表?是什么阻止我的Javascript应用成为一种激烈的竞争状况? 我知道需要很长时间的操作,例如Node中的IO操作和Web上的AJAX操作,要求它们是异步的并因此使用回调-但是谁在确定什么才是“长时间”?这些操作中是否有某种触发器可以将其从正常的“事件队列”中删除?如果不是,那么它们与简单的操作(如为变量赋值或遍历数组)之类的简单操作有何不同?似乎我们可以依靠它们以同步方式完成操作? 也许我什至没有正确地考虑这一点-希望有人可以让我直率。谢谢!

2
使用回调时,Javascript代码如何变得异步?
我一直在做很多在线阅读,试图弄清楚如何编写异步JavaScript代码。我的研究中出现的很多技术之一就是使用回调。当我了解如何编写和执行回调函数的过程时,我感到困惑的是,为什么回调似乎自动地使JavaScript执行异步。所以,我的问题是:在我的JavaScript代码中添加回调函数如何使所说的代码自动地异步?

4
异步+等待==同步?
偶然发现了有关发出异步Web请求的帖子。 除了简单性之外,如果在现实世界中,您所要做的就是发出一个异步请求并在下一行等待它,这与首先发出一个同步调用不是一样吗?

1
学习异步编程
关闭。这个问题是题外话。它当前不接受答案。 想改善这个问题吗? 更新问题,使它成为软件工程堆栈交换的主题。 4年前关闭。 异步非阻塞事件驱动的编程似乎风行一时。我对这一切意味着什么有基本的概念理解。但是,我不确定的是我的代码何时何地可以从异步中受益,或者如何使阻塞式IO成为非阻塞式。我敢肯定,我可以简单地使用一个库来做到这一点,但是我对更深入的概念以及自己实现它的各种方式更感兴趣。 是否有任何全面/权威书籍或其他资源在这个问题上(如GoF的设计模式,或K&R为C,TLDP对于像bash)的? (注意:我不确定这在功能上是否与我学习事件驱动编程有关的问题相同)

2
谁先进行了异步/等待?
Python在2015年在3.5中添加了async / await构造。Javascript社区朝着它迈进了一大步,并在2017年发布的ES8草案中增加了非常相似的实现(据我了解)。Typescript在2015年的1.7版中还添加了异步方法,使未经训练的人看起来完全像js异步方法。 C#在2012年添加了异步方法,这些方法看起来与async / await的所有其他实现类似,并且基于F#的行为类似但外观不同的异步工作流,该工作流于2010年在F#2.0中引入。这是我所知道的最早关于异步编程语言的示例-具有异步/等待对的C#和具有异步流的F#。 是否有较早的示例在此上下文中将关键字用作语言构造(或库)?从我有限的信息来看,似乎每个人都模仿了C#实现的优秀部分,但是C#是否从其他人那里复制了它呢?

1
Akka是否淘汰了JMS / AMQP消息代理?[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 4年前关闭。 我花了最后一周深入研究Akka文档,最终了解了什么是actor系统,以及它们解决的问题。 我对传统的JMS / AMQP消息代理的理解(和经验)是,它们存在以提供以下功能: 生产者和消费者之间的异步处理;和 消息传递保证,包括持久性,重试和回退 但是,如果没有所有必需的基础架构和运营开销,Akka是否可以提供此服务? 在Akka中,所有Actor通信都是异步且无阻塞的。和 在Akka中,SupervisorStrategies存在完成重试,后备和升级的功能。如果也需要的话,可以将Actor配置为持久存储到几乎任何类型的商店。 因此,这让我感到奇怪:如果我的应用程序使用Akka,是否需要将JMS / AMQP代理(例如ActiveMQ,RabbitMQ,Kafka)带入图片?换句话说,是否曾经有过这样的用例,那就是基于Akka的新应用程序还需要引入新的 JMS / AMQP代理集群?为什么或者为什么不? 唯一的论点是,也许我的Akka应用程序必须与另一个系统集成。但是在那种情况下,Akka-Camel模块使Akka可以利用Camel详尽无穷的,几乎无限的集成功能列表(TCP,FTP,ZeroMQ,这个列表不胜枚举……)。 有什么想法吗?

3
并行调用多个异步服务
我很少有彼此不依赖的异步REST服务。那就是在“等待” Service1的响应时,我可以调用Service2,Service3等。 例如,参考下面的代码: var service1Response = await HttpService1Async(); var service2Response = await HttpService2Async(); // Use service1Response and service2Response 现在,它们service2Response不再依赖service1Response并且可以独立获取。因此,不需要我等待第一服务的响应来呼叫第二服务。 我不认为我可以Parallel.ForEach在这里使用,因为它不是CPU限制的操作。 为了并行调用这两个操作,可以调用use Task.WhenAll吗?我看到的一个问题Task.WhenAll是它不会返回结果。要获取结果,我可以在致电task.Result后调用Task.WhenAll,因为所有任务都已经完成并且我需要获取我们所有的响应? 样例代码: var task1 = HttpService1Async(); var task2 = HttpService2Async(); await Task.WhenAll(task1, task2) var result1 = task1.Result; var result2 = task2.Result; // Use result1 and result2 就性能而言,此代码是否比第一个更好?我可以使用其他方法吗?

3
API网关(REST)+事件驱动的微服务
我有一堆微服务,这些服务根据API网关模式通过REST API公开。由于这些微服务是Spring Boot应用程序,因此我正在使用Spring AMQP来实现这些微服务之间的RPC风格的同步通信。到目前为止,一切进展顺利。但是,我对事件驱动的微服务体系结构了解得越多,对诸如Spring Cloud Stream之类的项目的了解越多,我就深信我可能会采用RPC同步方法以错误的方式进行操作(特别是因为我需要按比例缩放)以便每秒响应来自客户端应用程序的数百或数千个请求)。 我了解事件驱动架构背后的观点。我不太了解的是当坐在期望对每个请求都响应的模型(REST)后面时,如何实际使用这种模式。例如,如果我将我的API网关作为一个微服务,而另一个将存储和管理用户的微服务作为一个微服务,那么我该如何GET /users/1以纯粹的事件驱动方式对诸如a之类的事物进行建模呢?

1
NodeJS如何实现“非阻塞”?
我正在学习NodeJS,只是想澄清一些东西。到目前为止,在几本入门教程和书籍中,它们很早就描述了Node的“非阻塞”体系结构-或者说有可能(并建议整个观点)以非阻塞方式进行编码。 因此,例如,在我正在阅读以异步方式从数据库获取数据的书中给出了此示例。 http.createServer(function (req, res) { database.getInformation(function (data) { res.writeHead(200); res.end(data); }); }); 据我所知,发生的事情是Node调用了数据库,然后继续处理调用堆栈中下一步可能发生的任何事情。数据库请求完成后,将填充匿名回调函数中的数据变量,并将该函数添加到调用堆栈中(并在Node到达该堆栈时执行)。 我的问题是,究竟在处理数据库请求是什么?当然,Node必须同时阻止吗?负责数据库请求的是什么?或者,如果Node在等待对外部资源的异步HTTP GET请求,那么该请求又在做什么呢?

2
在单个方法中有效地混合使用同步和异步方法?
好的,听起来很奇怪,但是代码非常简单,可以很好地说明情况。 public virtual async Task RemoveFromRoleAsync(AzureTableUser user, string role) { AssertNotDisposed(); var roles = await GetRolesForUser(user); roles.Roles = RemoveRoles(roles.Roles, role); await Run(TableOperation.Replace(roles)); } (我知道我在下面的摘要中说的有点像,但以上是实际生产代码中的一种实际方法,该代码实际上正在执行我在这里要问的事情,并且我实际上对您的实际审查很感兴趣相对于异步/等待模式的正确性。) 我现在使用async/ awaitmore越来越多地遇到这种模式。该模式由以下事件链组成: 等待初始呼叫,这会给我一些我需要处理的信息 同步处理该信息 等待最后的通话,以保存更新的工作 上面的代码块通常是我如何处理这些方法。我await是第一个电话,我必须这样做,因为它是异步的。接下来,我要做的工作是不受IO或资源限制的,因此不是异步的。最后,我保存了我的工作,这也是一个async电话,而不再是我的工作await。 但这是处理这种模式的最有效/正确的方法吗?在我看来,我可以跳过await上一个电话,但是如果失败了怎么办?我是否应该使用Task诸如ContinueWith将同步工作与原始调用链接在一起的方法?我现在只是不确定我是否正确处理了这一点。 给定示例中的代码,是否有更好的方法来处理此async / sync / async方法调用链?

1
在C#5.0中模糊异步和常规函数之间的界限
最近,我似乎对C#5.0 的惊人异步等待模式不够了解。我这辈子去哪了 我对简单的语法感到非常兴奋,但是我遇到了一个小困难。我的问题是异步函数的声明与常规函数完全不同。由于只有异步函数可以等待其他异步函数,因此当我尝试将一些旧的阻止代码移植到异步时,我产生了必须转换的函数的多米诺骨牌效应。 人们一直称其为僵尸大批出没。当异步在您的代码中被咬时,它将不断变得越来越大。移植过程并不困难,只需将其async放入声明中并用来包装返回值Task<>。但是在移植旧的同步代码时,一遍又一遍地执行此操作很烦人。 在我看来,如果两种函数类型(异步和普通旧同步)具有完全相同的语法,那将是自然得多的。如果是这种情况,移植将花费零的精力,我可以在两种形式之间轻松切换。 我认为如果遵循以下规则,这可能会起作用: 异步函数不再需要async声明。他们的返回类型不必包装Task<>。编译器将在编译期间自行识别异步函数,并根据需要自动执行Task <>包装。 不再需要对异步函数进行“一劳永逸”的调用。如果要调用异步函数,则需要等待它。无论如何,我几乎都不用一劳永逸,疯狂的比赛条件或僵局的所有例子似乎总是基于它们。我认为他们与我们试图利用的同步思维过于混乱和“脱节”。 如果您真的不能一劳永逸,那将有特殊的语法。无论如何,它不会成为我正在谈论的简单统一语法的一部分。 您需要表示异步调用的唯一关键字是await。如果您正在等待,则该调用是异步的。如果您不这样做,则该呼叫是普通的老式同步呼叫(请记住,我们不再具有即兴即弃的功能)。 编译器将自动识别异步函数(因为它们不再有特殊的声明了)。规则4使得此操作非常简单-如果函数await内部有调用,则它是异步的。 能行吗?还是我错过了什么?这种统一的语法更加流畅,可以完全解决僵尸的侵扰。 一些例子: // assume this is an async function (has await calls inside) int CalcRemoteBalanceAsync() { ... } // assume this is a regular sync function (has no await calls inside) int CalcRemoteBalance() { ... } // now …

1
当异步任务使用户体验不佳时
我正在编写一个COM插件,该插件扩展了迫切需要它的IDE。这里涉及许多功能,但是为了这篇文章,我们将其缩小到2: 有一个“代码资源管理器”工具窗口,其中显示一个树状视图,允许用户浏览模块及其成员。 有一个“代码检查”工具窗口,其中显示一个datagridview,可让用户浏览代码问题并自动修复它们。 两种工具都有一个“刷新”按钮,用于启动异步任务,该任务将解析​​所有打开的项目中的所有代码。该代码浏览器使用的解析结果建立树形视图和代码评审使用的解析结果,以找出代码问题并显示其结果的datagridview。 我在这里想要做的是在功能之间共享解析结果,以便在代码浏览器刷新时,代码检查会知道它并可以刷新自身,而无需重做代码浏览器刚刚进行的解析工作。 因此,我做了什么,将解析器类设置为事件提供者,这些功能可以注册到: private void _parser_ParseCompleted(object sender, ParseCompletedEventArgs e) { Control.Invoke((MethodInvoker) delegate { Control.SolutionTree.Nodes.Clear(); foreach (var result in e.ParseResults) { var node = new TreeNode(result.Project.Name); node.ImageKey = "Hourglass"; node.SelectedImageKey = node.ImageKey; AddProjectNodes(result, node); Control.SolutionTree.Nodes.Add(node); } Control.EnableRefresh(); }); } private void _parser_ParseStarted(object sender, ParseStartedEventArgs e) { Control.Invoke((MethodInvoker) delegate …
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.