zha*_*hou 2 javascript node.js async-await
根据MDN,
异步函数声明定义了一个异步函数
我理解它,因为该函数将被视为异步过程,就像setTimeout某个数据库请求一样。例如,在下面的示例中,该过程应在数字之间的某个位置输出“ main”。
let func2 = async () => {
for (let i = 0; i < 51; i ++) {
console.log(i);
}
}
(async () => {
func2();
console.log("main");
})()
Run Code Online (Sandbox Code Playgroud)
但是,就像整个过程是同步的一样,“ main”总是在最后被控制台。我理解错了什么?
如果同步代码仍然是同步的,那么目的是async什么?只允许await在其内部提供一些幻想的方法来返回Promise?
异步会使其内部的所有内容异步吗?
不,不是的。函数中的代码仍将同步运行,并在运行时阻止事件循环。
如果同步代码仍处于同步状态,那么异步的目的是什么?只允许在其中等待并提供某种幻想的方式来返回Promise?
是的,主要是针对await。
但是,在某些情况下,它会自动用承诺包装代码,这很有用。例如,它会自动捕获所有抛出的异常,并将其转变为被拒绝的承诺。有时这很有用。有关其他有用性的示例,请参见本文的“错误处理”部分:JavaScript的Async / Await导致Promises Away消失的6个原因。
但是,async关键字的主要功能是定义一个可以使用的功能await。这就是ES7的设计师决定进行await工作的方式。
仅供参考,如果await函数中有一个等待诺言的内容,则将导致该函数在的点早返回await。它将在那时返回并返回承诺。您正在等待的操作将已经开始,并且直到解决了等待的诺言之后,该功能的其余部分才会执行。因此,使用可以await使某些代码稍后执行。但是,就像之前的代码一样await,即使该函数在await解析后恢复运行,该函数中的Javascript仍将保持同步和阻塞状态(直到另一个await或直到return)。
将其包装在Promise中并检测其完成时间.then()将在.then()调用处理程序时推迟到事件循环的下一个刻度为止。因此,这.then()会稍有延迟,因为您将其包装在promise中,然后使用.then(),但是代码运行的时间不变。它仍然是同步和阻塞的。
在Javascript中,获取同步代码并使之异步的唯一方法是:
在另一个进程中运行它,并使用进程间通信来传达结果。
在使用本机线程或某些其他OS异步接口执行实际工作的本机代码加载项中重写代码,然后从您的加载项提供到Javascript的异步接口(通常是一个返回承诺或通过以下操作通知完成的接口)回调)。现在这是node.js等异步功能的fs.readFile()工作。他们有一个本机代码实现,该实现立即返回,然后在实现中使用本机线程,并通过回调通知完成。
使用一些node.js附加组件为您完成其中的一些工作。 有一些旨在提供线程的加载项。
在节点版本10.5+中使用node.js线程,并按其要求进行限制。这是一篇有关以下主题的文章:Node 10.5.0中的线程:实用介绍
不,异步函数内的主体在调用时运行,但在await表达式中暂停。如果没有 to await,该函数将像普通函数一样运行,但它返回一个承诺。
但是,如果有await,则暂停执行并继续事件循环。当等待的承诺在当前事件循环完成后的某个时间解决时,它会从停止的地方开始。例如,比较何时在此处记录“main”与您的示例。
let func2 = async () => {
console.log("Start")
for (let i = 0; i < 10; i ++) {
if(i == 5) {
await new Promise(resolve => setTimeout(resolve, 200))
}
console.log(i);
}
}
(async () => {
func2().then(() => console.log('done'));
console.log("main");
})()Run Code Online (Sandbox Code Playgroud)
考虑async函数的另一种方式是考虑它们与生成器的关系。我喜欢将其await视为一种yield. 例如,我们唯一需要的身体变化func2,以获得相同的行为被换await为yield:
function* func2() {
console.log("Start")
for (let i = 0; i < 10; i++) {
if (i == 5) {
yield new Promise(resolve => setTimeout(resolve, 0))
}
console.log(i);
}
return "done"
}
let gen = func2()
gen.next().value.then(() => console.log(gen.next().value))
console.log("main")Run Code Online (Sandbox Code Playgroud)
async/await只是使这对于常见用例更容易和更直观。
| 归档时间: |
|
| 查看次数: |
1726 次 |
| 最近记录: |