异步 JavaScript 和 I/O
Async JavaScript and I/O
刚刚发现异步 JavaScript,我一直在尝试概念化使用它的意义所在:当要解决问题时,我希望能够从一开始就说:“这是我应该使用async JavaScript!"的问题,当然也是相反的。
我的第一个想法是开始(慢慢地)将 所有内容 转换为异步,以便更好地在函数之间交错。然后我意识到这种策略存在巨大的矫枉过正。有很多函数不需要异步,比如
var add = (a,b) => { return a+b;}
所以现在我在想,从概念上讲,异步 JavaScript 的存在主要是为了更好地 I/O 处理。我认为它可能适用的唯一其他领域是长期 运行 脚本,以免阻塞 JavaScript 的单线程。
Anything/anywhere 在其他地方我应该说“这是异步的工作!”?
javascript 中有几个使用异步逻辑的用例。一个常见的例子是执行 http 请求。正如您已经指出的,您不想在等待服务器响应或用户输入时阻止脚本执行。
JavaScript 应用程序大量使用所谓的承诺。承诺一旦被解决或拒绝,就会发出一个事件。另一种可能性是通过回调函数:
console.log(1)
const wait = function () {
return setTimeout(function() {
console.log(3)
}, 50)
}
wait()
console.log(2)
使用承诺的示例:
console.log(1)
const wait = function() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve()
}, 50)
})
}
wait().then(() => console.log(3))
console.log(2)
希望这能以某种方式澄清。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
在 JavaScript 中,如果您计划使用本质上是异步的 API,那么您只能从 async
中真正受益,即可以做一些非 JavaScript 任务“在引擎盖下”,然后将作业(事件)放在 JavaScript 作业(事件)队列中。此作业可以是回调或承诺解决方案。
此类 API 的一些示例是:
- 预定:
setTimeout
, setInterval
- 推迟:
queueMicrotask
- HTTP 请求:
XMLHttpRequest
, fetch
- 绘画周期:
requestAnimationFrame
- 另一个话题:Web Workers
- 本地数据库:indexedDB
- ...任何其他异步(可能基于承诺)API:像 axios, mongodb,...和许多其他众所周知的 APIs
最重要的是,如果您的函数使用 await
,您实际上只需要 async
。不使用 await
的 async
函数没有多大意义。即使 await
-less 函数会 return 一个承诺,那么它仍然不需要声明 async
.
另一方面,如果您使用 API 的一些异步行为,那么如果 API 没有(还)公开基于承诺的 API。例如,这里有一行常见的代码来 promisify setTimeout
:
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
...所以现在在 async
函数中,您可以引入 100 毫秒的“暂停”:
await delay(100);
如果您正在使用 promises,并且发现您的代码有 .then
个链,那么这是转换为 async
/await
语法的一个很好的用例。
刚刚发现异步 JavaScript,我一直在尝试概念化使用它的意义所在:当要解决问题时,我希望能够从一开始就说:“这是我应该使用async JavaScript!"的问题,当然也是相反的。
我的第一个想法是开始(慢慢地)将 所有内容 转换为异步,以便更好地在函数之间交错。然后我意识到这种策略存在巨大的矫枉过正。有很多函数不需要异步,比如
var add = (a,b) => { return a+b;}
所以现在我在想,从概念上讲,异步 JavaScript 的存在主要是为了更好地 I/O 处理。我认为它可能适用的唯一其他领域是长期 运行 脚本,以免阻塞 JavaScript 的单线程。
Anything/anywhere 在其他地方我应该说“这是异步的工作!”?
javascript 中有几个使用异步逻辑的用例。一个常见的例子是执行 http 请求。正如您已经指出的,您不想在等待服务器响应或用户输入时阻止脚本执行。
JavaScript 应用程序大量使用所谓的承诺。承诺一旦被解决或拒绝,就会发出一个事件。另一种可能性是通过回调函数:
console.log(1)
const wait = function () {
return setTimeout(function() {
console.log(3)
}, 50)
}
wait()
console.log(2)
使用承诺的示例:
console.log(1)
const wait = function() {
return new Promise((resolve, reject) => {
setTimeout(() => {
resolve()
}, 50)
})
}
wait().then(() => console.log(3))
console.log(2)
希望这能以某种方式澄清。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise
在 JavaScript 中,如果您计划使用本质上是异步的 API,那么您只能从 async
中真正受益,即可以做一些非 JavaScript 任务“在引擎盖下”,然后将作业(事件)放在 JavaScript 作业(事件)队列中。此作业可以是回调或承诺解决方案。
此类 API 的一些示例是:
- 预定:
setTimeout
,setInterval
- 推迟:
queueMicrotask
- HTTP 请求:
XMLHttpRequest
,fetch
- 绘画周期:
requestAnimationFrame
- 另一个话题:Web Workers
- 本地数据库:indexedDB
- ...任何其他异步(可能基于承诺)API:像 axios, mongodb,...和许多其他众所周知的 APIs
最重要的是,如果您的函数使用 await
,您实际上只需要 async
。不使用 await
的 async
函数没有多大意义。即使 await
-less 函数会 return 一个承诺,那么它仍然不需要声明 async
.
另一方面,如果您使用 API 的一些异步行为,那么如果 API 没有(还)公开基于承诺的 API。例如,这里有一行常见的代码来 promisify setTimeout
:
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
...所以现在在 async
函数中,您可以引入 100 毫秒的“暂停”:
await delay(100);
如果您正在使用 promises,并且发现您的代码有 .then
个链,那么这是转换为 async
/await
语法的一个很好的用例。