Javascript 为什么';等待&x27;需要';异步';在函数定义中
我目前正在学习Dart,但这也适用于JavaScript世界目前正在发生的事情,而且C#似乎也使用相同的模式 在Dart中,任何使用Javascript 为什么';等待&x27;需要';异步';在函数定义中,javascript,asynchronous,promise,dart,Javascript,Asynchronous,Promise,Dart,我目前正在学习Dart,但这也适用于JavaScript世界目前正在发生的事情,而且C#似乎也使用相同的模式 在Dart中,任何使用await的函数本身必须通过async标记为异步,如下所示: import "dart:html"; main() async { var context = querySelector("canvas").context2D; var running = true; while (running) { var time = await wi
await
的函数本身必须通过async
标记为异步,如下所示:
import "dart:html";
main() async {
var context = querySelector("canvas").context2D;
var running = true;
while (running) {
var time = await window.animationFrame;
...
}
}
这对我来说没有意义。如果一个函数正在等待一个异步函数完成,那么它不被认为是阻塞的吗?为什么JS和Dart要求将其标记为异步?难道不是相反吗
对我来说,如果调用函数必须使用async
关键字(如果它调用任何定义中也包含它的函数),那么它将更有意义。在此模式中,await
将用于将异步函数转换为同步函数
这种方法还可以避免重复的函数,因为现在,库似乎总是有
func()
和funcSync()
或funcAsync()
我不确定你的问题与C有什么关系,但是wait
是C中最不幸的关键字选择<如果将代码>等待理解为在
之后继续甚至在
之后继续,则更容易理解。当执行遇到wait
时,它将暂停当前函数,并返回其调用者。一旦等待的任务
完成,调用方需要结果时(从其自身的等待
表达式)在等待
之后继续执行。这是对“幕后”情况的根本误解,我假设javascript异步/等待实现是镜像的(至少在概念上)是.NET世界(起源于F#)
基本上:
在这个扩展的上下文中,关键字是有意义的:
只要把async和await看作是不可见的回调,async表示什么时候可以监听,而await就是监听的实际功能。在Dart
async
中,表示包含await
的代码需要重写。
async
/await
只是未来的语法糖。然后()
基本API,在编译和执行之前,代码被重写为这种基于规范的未来的形式
因此,wait
不会造成代码阻塞
还有其他受支持的标记,如发电机的*sync
和*async
另见
-
-异步
/等待
的基本语义在F#、VB、C#、Python、Dart、Hack和JavaScript中都是相同的。所以我认为这个问题从其他语言中已经有了足够的答案。但由于它已经被重新打开
如果一个函数正在等待一个异步函数完成,那么它不被认为是阻塞的吗
不,这样想:
- “异步”表示“不阻止调用线程”
- “同步”表示“阻止调用线程”
在异步方法/函数中,方法/函数可以在等待
点暂停,但暂停时不会阻止调用线程。函数以串行方式(一次一条语句)运行,但异步运行(不阻止调用线程)
对我来说,如果调用函数必须使用async关键字(如果它调用的任何函数在其定义中也包含async关键字),那么这将更有意义
这就是它的工作原理。await
使用承诺/未来/任务返回方法/函数,async
将方法/函数标记为能够使用await
这样也可以避免重复的功能
这在历史上阻止命令式语言时是不可能的。方法/函数要么在调用线程完成之前阻止它,要么不阻止它。它是同步的或异步的
不过,异步方法/函数有一些有趣的替代方法:
Go不是历史上的阻塞;您可以将其视为一种语言,其中每个方法/函数都可能是异步的;在任何其他运行时这样做都将是灾难性的,但Go通过实现带有消息传递的严格goroutine系统来避免这些问题—不允许共享内存或线程
另一个例子是纯函数式语言,Future只是另一个monad,不需要对async
/wait
关键字提供特殊的编译器支持。AFAIK异步和阻塞的区别在于,在一个线程中可以有多个异步进程(其中一个是