在 Javascript 中,如何将请求的回调函数的结果合并到运行代码中?

问题描述 投票:0回答:1

我来自 PIC 汇编语言编程,程序通常连续运行。我现在已经学习 JavaScript 很长一段时间了,但是当回调函数作为调用异步函数的参数给出时,我对它们的使用有点受阻。我确实意识到回调已经被“永远”解释了,但我已经从头到尾读了大约 10 本书,但没有得到明确的答案。

首先,大多数描述都“掩盖”了异步函数在代码中的实际实现方式。我现在发现这通常不是 Javascript 的一部分,而是底层主机代码(浏览器,甚至可能是浏览器运行的操作系统)的一部分。但是 Javascript 必须有一种机制来运行本身不属于 Javascript 语言一部分的函数,并且底层主机必须有一种允许 Javascript 继续运行的机制。我从未见过任何这方面的代码。我想知道主机代码到底是如何将特定的 Javascript 块放入事件队列中的?这一切看起来都相当安静。

当谈到回调的使用时,我有以下假设(以此类推),结果证明是错误的。 我正在做饭,需要一些盐,但我没有。我派朋友去买一些盐,但我不想停止做饭。所以我的异步函数是 goBuySomeSalt(nameOfShop, putItOnTable)。我继续做饭,并期望盐稍后到达(然后放入 putOnTable())。当盐到达时,我会在烹饪中使用它。

Javascript 似乎不允许这样做。回调的解释几乎普遍表示,当异步函数完成时,将会调用回调。所以当我的朋友回来时我想用我的盐。但我不能,因为我还在做饭。在我完成烹饪之前似乎无法使用盐,因为我的朋友在活动队列的后面等待,只有当我完成我正在做的事情时,他们才会把盐放在桌子上。 因此我对盐的要求基本上是无用的。 我错过了什么吗?我可以在烹饪过程中“轮询”盐吗?盐到货后可以通知我吗? (请注意;我已经读过有关承诺等的内容)

下面是我的代码来说明这一点:

function a(){ setTimeout(d, 1000); console.log ("Please fetch some salt!") } function d(){ console.log("Here's your salt - sorry I'm too late");} a(); for (let i = 0; i < 4000000000; i++) { if (i%1000000000 == 0) { console.log ("Cooking");} } console.log ("finished cooking - but used no salt!!")

输出的顺序是:

“请拿点盐来!” “烹饪” “烹饪” “烹饪” “烹饪” “煮好了——但是没有放盐!!” “这是你的盐 - 抱歉我来晚了”

javascript asynchronous callback
1个回答
0
投票

函数是一等公民,因此每个函数都被视为一个单独的范围,并在返回输出之前在其内部进行完全处理。

例如:

function a() { console.log("hello"); } function b(c) { console.log("good bye"); c(); }

b(a) 将导致

good bye hello

这是因为函数 b 中首先调用 b,然后调用 a 

现在 - 如果我们这样做:

setTimeout(a,0); setTimeout(b(a), 0);

结果
应该

是 你好 再见 你好 但实际上是

good bye hello hello

这是因为每个函数在移动到下一个函数之前都会完全评估其状态,在这种情况下,b(a) 是一个函数,而不是只是一个函数引用的 a 

现在如果我们这样做:

setTimeout(a(),0); setTimeout(b(a), 0);

结果符合预期:

hello good bye hello

这是因为 a() 现在是一个函数,这导致它在 b(a) 之前完全执行。

因此,这完全取决于回调是函数、指针还是其他东西,以及它们发生的顺序,并且每个函数在移动到下一个函数并更新状态之前都会被完全评估。

希望这有帮助

© www.soinside.com 2019 - 2024. All rights reserved.