为什么要有一个异步功能才能使用await?为什么我们不能在没有异步的情况下使用await? JS默认也是异步的,这只会增加混乱。
更新: 我看到一些小伙子搁置了我的问题,所以我会尽力阐述。 我只是好奇为什么这行不通:
some code
let users = await getUsers();
some code
为什么要在异步内部使其正常工作,即
$(async function() {
some code
let users = await getUsers();
some code
});
答案 0 :(得分:1)
JS默认也是异步的...
否,默认情况下,JavaScript不是异步的。 JavaScript的唯一异步功能是相当新添加的:
async
/ await
JavaScript通常用于与异步事物进行交互的环境(例如DOM中的事件处理程序,或Node.js中的I / O完成),但是JavaScript不是异步的(除了上述之外)。
在多年{@ 3}}的ECMAScript规范的编辑Allen Wirfs-Brock中,JavaScript ...
(具有)一个可观察到的同步执行模型。除了通过Atomics / SAB以外,没有可观察到的共享状态竞争条件。
回到您的问题:
为什么要使用await功能才能使用await?
不久之后,the words of就可以完成top level await
proposal的工作,而无需使用模块。到了第3阶段。
但是答案是await
是使用诺言的句法糖,诺言的规则之一是您要么处理错误,要么将链返回给调用方(这样它就可以处理错误或返回调用者。链接到其调用方)。 await
不处理错误,因此必须将链返回给调用方。这样做的方式是async
函数始终返回一个诺言,并且该诺言链接到诺言await
等待。
也就是说,这个:
async function foo() {
const thingy = await somethingAsyncReturningAPromise();
return thingy.foo;
}
从概念上讲(但不是从字面上看):
function foo() {
return somethingAsyncReturningAPromise()
.then(thingy => thingy.foo);
}
如果somethingAsyncReturningAPromise
中出现问题,则foo
返回的承诺将被拒绝-错误会传播到调用方。
据我从顶层await
提议中得知,它只是允许模块顶层的未处理拒绝为未处理拒绝。因此,就像这段代码会导致未处理的错误一样:
null.doSomething();
异步模块中的以下代码将导致未处理的拒绝:
await somethingThatReturnsAPromiseAndRejects();
答案 1 :(得分:0)
为什么要有一个异步功能才能使用await?为什么我们不能在没有异步的情况下使用await?
因为async
/ await
对于承诺来说只是“ 语法糖”。如果该函数是异步的,则它将返回一个Promise。不返回承诺就不可能有“等待”行为。该函数异步的事实必须明确标记。
JS默认也是异步的,这只会增加混乱。
此陈述过于“简化”。尽管JS本质上是异步的,但由于事件循环的存在,但这并不意味着每个函数都具有异步行为。这不会增加混乱。您可能由于误解JS的工作原理而感到困惑。您应该阅读有关Promises的内容,当您看到async
/ await
时,这些内容就在幕后。
答案 2 :(得分:0)
JavaScript具有基于任务的并发性。从根本上讲,这意味着代码块(任务)将同步运行而不会被中断,直到达到某个断点(任务结束)为止。这有一些优点:
1)您确实具有并发性,例如网络调用不会同时阻止您的脚本执行其他操作(因此消耗网络请求的任务只有在网络请求完成后才能运行,其他任务可以在此期间完成)。
2)另一方面,您没有并发的突变,这消除了很多问题(let a = 1; a += 1;
可以评估为3,您需要使用锁/信号灯来防止这些问题,请参见Java及其他)。
现在async
/ await
允许您定义此类任务:
异步功能可以分为任务,await
作为断点:
let a = 1;
async function stuff() {
a = a + 1; // this is totally secure, as no other code might run in the meantime
a = a + await other(); // this is unsafe, as we await, which means that other tasks might be executed in the meantime.
}
如果您要“等待非异步函数”,这基本上意味着您将不知道某个函数调用是否同步运行(意味着:同时没有其他代码在运行):
function dangerous() { await stuff(); }
let a = 1;
a = a + dangerous(); // does that work or not? Can a be manipulated in the meantime?
因此,根据您的建议,您基本上将消除任务之间的边界,每个代码可能会在每个任务之间运行。因此,最终会导致混乱,如果您想提高生产力,那么混乱就不好。