正如牛仔在此处的评论中所说的,我们所有人都想以类似于以下的样式来编写[非阻塞JavaScript]异步代码:
try
{
var foo = getSomething(); // async call that would normally block
var bar = doSomething(foo);
console.log(bar);
}
catch (error)
{
console.error(error);
}
”
因此人们提出了解决该问题的方法,例如
但是,这些都不比上面的同步样式代码更简单易懂。
那么,为什么JavaScript编译器/解释器无法仅不阻塞我们当前称为“阻塞”的语句呢?
那么,如果我们以异步方式编写的话,为什么JavaScript编译器/解释器无法处理AS之上的同步语法呢?”
例如,经过getSomething()
上面的处理,编译器/解释器可能会说“此语句是对[文件系统/网络资源/
…]的调用,因此我将做一个笔记来监听来自该调用的响应,并在同时继续处理我的事件循环”。调用返回时,执行可以进行到doSomething()
。
您仍将保留流行的JavaScript运行时环境的所有基本功能
这只是语法上的一个调整,这将允许解释器在IT进行异步操作检测时暂停对任何给定代码的执行,并且不需要回调,而是仅在异步调用后的代码行中继续执行代码,而无需进行回调返回。
正如杰里米所说
JavaScript运行时中没有什么可以抢先暂停给定任务的执行,允许其他一些代码执行一段时间,然后继续执行原始任务
为什么不?(例如,“为什么不可以?” …我对历史课程不感兴趣)
开发人员为什么要关心语句是否被阻塞?计算机用于自动化人类不擅长的事物(例如,编写非阻塞代码)。
你也许可以用
"use noblock"
; "use strict";
)打开整个页面代码的“模式”。编辑:"use noblock"
; 是一个错误的选择,并误导了一些我试图完全改变普通JavaScript运行时性质的答案。类似的东西'use syncsyntax';
可能会更好地描述它。parallel(fn, fn, ...);
允许您在运行中并行运行的语句"use syncsyntax"
; 模式-例如,允许一次启动多个异步活动wait()
,该语法将代替setTimeout()
in "use syncsyntax"
; 模式编辑:
例如,代替编写(标准回调版本)
function fnInsertDB(myString, fnNextTask) {
fnDAL('insert into tbl (field) values (' + myString + ');', function(recordID) {
fnNextTask(recordID);
});
}
fnInsertDB('stuff', fnDeleteDB);
你可以写
'use syncsyntax';
function fnInsertDB(myString) {
return fnDAL('insert into tbl (field) values (' + myString ');'); // returns recordID
}
var recordID = fnInsertDB('stuff');
fnDeleteDB(recordID);
该syncsyntax
版本的处理方式与标准版本完全相同,但了解程序员的意图要容易得多(只要您了解syncsyntax
所讨论的代码会暂停执行)。
为什么不?没有理由,只是没有完成。
在2017年,它 已 在ES2017中完成:async
函数可以用于await
等待,无阻塞地等待承诺的结果。如果getSomething
返回promise(请注意await
)并且位于async
函数内部,则可以这样编写代码:
try
{
var foo = await getSomething();
var bar = doSomething(foo);
console.log(bar);
}
catch (error)
{
console.error(error);
}
(我曾假设您只打算getSomething
异步,但两者都可能是异步的。)
实时示例(需要最新的浏览器,例如最新的Chrome):
function getSomething() {
return new Promise((resolve, reject) => {
setTimeout(() => {
if (Math.random() < 0.5) {
reject(new Error("failed"));
} else {
resolve(Math.floor(Math.random() * 100));
}
}, 200);
});
}
function doSomething(x) {
return x * 2;
}
(async () => {
try
{
var foo = await getSomething();
console.log("foo:", foo);
var bar = doSomething(foo);
console.log("bar:", bar);
}
catch (error)
{
console.error(error);
}
})();
The first promise fails half the time, so click Run repeatedly to see both failure and success.
您已用NodeJS标记了您的问题。如果将Node
API包装在Promise中(例如,使用promisify),则可以编写异步运行的漂亮的直接同步代码。