gpt4 book ai didi

javascript - Raku 相当于 JavaScript 的 `setTimeout(fn, 0)` ?

转载 作者:行者123 更新时间:2023-12-05 00:26:02 26 4
gpt4 key购买 nike

JavaScript 的事件循环使用消息队列来安排工作,并在开始下一条消息之前运行每条消息直到完成。因此,JavaScript 代码中的一个小众但令人惊讶的常见模式是安排一个函数在队列中的当前消息已使用 setTimeout(fn, 0) 处理后运行。 .例如:

setTimeout(() => {console.log('first')}, 0);
console.log('second');
// OUTPUT: "second\nfirst"
(参见 MDN's description 了解更多详情。)
Raku's 是否提供任何类似的方式来在所有当前安排的工作完成后立即安排工作?根据我对 Raku 并发模型的理解(主要来自 this 6guts post),Raku 似乎使用了类似的消息队列(如果有错请纠正我!)。我最初以为 Promise.in(0).then: &fn是直接等价的:
my $p = Promise.in(0).then: { say 'first' }
say 'second';
await $p;
# OUTPUT: «second\nfirst» # ...usually
然而,在多次运行上述代码后,我意识到它只是设置了一个竞争条件和 'first'有时是第一个。那么,是否有任何 Raku 代码可以提供相同的行为?如果是这样,这种行为是 Raku/Roast 决定的有意语义的结果,而不是(可能是临时的)实现细节的结果?

最佳答案

无序
Raku 没有有序的消息队列。它有一个需要做的事情的无序列表。

# schedule them to run at the same second
# just to make it more likely that they will be out of order
my $wait = now + 1;

my @run;
for 1..20 -> $n {
push @run, Promise.at($wait).then: {say $n}
}
await @run;
这可以按任何顺序打印数字。
1
2
3
4
5
6
7
8
11
12
13
14
15
16
17
18
9
10
19
20
Raku 实际上是多线程的。如果你给它足够的工作,它将使用你所有的 cpu 核心。
这意味着在当前队列中的所有内容完成后,永远无法说运行它。
即使我只是使用 start ,它有时可能会出现故障。
my @run;
for 1..20 -> $n {
push @run, start {say $n}
};
await @run;
您可以在它开始乱序打印之前运行数百次,但它最终会这样做。
即使你去低级并使用 $*SCHEDULER.cue ,不能保证它会在其他所有内容之后运行。
my @nums;
for 1..100 -> $n {
$*SCHEDULER.cue: {push @nums, $n; say $n}
}
say @nums;
@nums 不仅可能出现故障,数组可能不会包含所有值,因为每个线程都可能破坏另一个线程正在执行的操作。
在幕后,安排运行的 Promise 方法最终调用 $*SCHEDULER.cue以某种方式。
安排其他事情
您可以告诉 Raku 在执行其他操作后运行您的代码。
my $p = Promise.in(1);
my $p2 = $p.then: {say 'first'}
my $p3 = $p.then: {say 'second'}

react {
whenever start say('first') {
whenever start say('second') {
}
}
}
不过,您需要引用那件事。
减缓
如果 Raku 确实有办法在当前安排的事件之后运行事物,那么它必须跟踪正在运行的内容并确保您的代码在它们完成之前不会运行。
my $a = start {

# pointless busy-work that takes two seconds
my $wait = now + 2;
my $n = 0;
while now ≤ $wait {
$n++
}
say $n; # make sure the loop doesn't get optimized away

say 'first';
}

my $b = start say 'second';

await $a, $b;
second
1427387
first
如果那确保 $b追赶 $a ,则不会对 $b 进行任何操作整整两秒钟。
相反,它只会导致 $b在另一个线程上运行,因为正在处理 $a 的线程目前正忙。
这是一件好事,因为如果 $b也很慢。我们将安排两个缓慢的事情按顺序而不是并行运行。
Javascript
我认为它目前在 Javascript 中工作的唯一原因是因为它似乎没有利用多个 cpu 内核。或者它有类似 GIL 的东西。
我编写的 Raku 代码的 4 核 CPU 利用率为 500%。 (英特尔超线程 CPU,其中一个核心似乎是 2 个核心)
我不确定您是否可以对单个 Javascript 程序执行相同的操作。

关于javascript - Raku 相当于 JavaScript 的 `setTimeout(fn, 0)` ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67679309/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com