正如牛仔在此处的评论中所说的,我们所有人都想以类似于以下的样式来编写[非阻塞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()。
getSomething()
doSomething()
您仍将保留流行的JavaScript运行时环境的所有基本功能
这只是语法上的一个调整,这将允许解释器在IT进行异步操作检测时暂停对任何给定代码的执行,并且不需要回调,而是仅在异步调用后的代码行中继续执行代码,而无需进行回调返回。
正如杰里米所说
JavaScript运行时中没有什么可以抢先暂停给定任务的执行,允许其他一些代码执行一段时间,然后继续执行原始任务
为什么不?(例如,“为什么不可以?” …我对历史课程不感兴趣)
开发人员为什么要关心语句是否被阻塞?计算机用于自动化人类不擅长的事物(例如,编写非阻塞代码)。
你也许可以用
"use noblock"
"use strict";
'use syncsyntax';
parallel(fn, fn, ...);
"use syncsyntax"
wait()
setTimeout()
编辑:
例如,代替编写(标准回调版本)
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所讨论的代码会暂停执行)。
syncsyntax
为什么不?没有理由,只是没有完成。
在2017年,它 已 在ES2017中完成:async函数可以用于await等待,无阻塞地等待承诺的结果。如果getSomething返回promise(请注意await)并且位于async函数内部,则可以这样编写代码:
async
await
getSomething
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),则可以编写异步运行的漂亮的直接同步代码。