是否有任何尝试将C# 5.0 中的async/await功能引入任何可以编译为 JavaScript 的语言(例如 CoffeScript)?(所以它可以在 Web 浏览器或 node.js 中使用。)
11 回答
异步在 JavaScript 和谐的功能列表中。到目前为止,已经有很多尝试在浏览器或节点中提供此类功能,但它们似乎都与和谐提议不兼容:
- 可以使用 JS1.7 生成器模拟异步(请参阅task.js)。V8 尚不支持开箱即用(无实验模式),但可在 FF 中使用。可能traceur或Masacra编译器可用于将生成器带到其他环境。
- 有node-fibers库为节点中的异步编程提供了其他机制(尽管会降低性能)。此处描述了基于 v8cgi 的其他尝试。
- Rhino 有开箱即用的延续,提供了很好的选择。这就是为什么Ringo.js可能值得一看。
- 很少有基于 js2js 翻译的解决方案可用,例如:jscx、NarrativeJS、jwacs、StratifiedJS。一些支持与节点的集成。
- 有许多 promise/future 库试图在不扩展语法的情况下解决回调问题,但是它们都存在可组合性问题,即不能使用跨回调的循环等语言结构。
async/await 看起来将出现在 ECMAScript 7中。该提案于 2014 年 1 月被接受进入规范流程的第 1 阶段。
好消息是 Google 的traceur 编译器已经支持它,所以你今天就可以开始使用它了。
示例语法:
async function asyncValue(value) {
await timeout(50);
return value;
}
async/await 也在TypeScript 路线图上。
我不熟悉 C#,但听起来你正在寻找的是某种延续,所以而不是写
fs.readFile 'foo.txt', (err, data) ->
myFunc data
你可以改为写类似的东西
data = &fs.readFile 'foo.txt' # not a real syntax
myFunc data
这不是 JavaScript 或 CoffeeScript 提供的。但是,还有其他几个编译器可以做这样的事情:
另请参阅:CoffeeScript wiki 上编译为 JavaScript 的语言列表。
是的,你甚至不需要编译它,因为它只是一个简单的 JavaScript 库。
我的一个名为sharpnr.js 的项目旨在使用C#(当然还有.NET)的强大功能来扩展JavaScript,例如await/async 或LINQ。
该库目前处于测试阶段,但它很稳定,几乎支持所有语句(例如循环、开关、if),并且可以与现有库(如 jQuery)很好地配合使用。
await/async 语法几乎与 C# 版本相同:
var getAsync = async(function(url) {
var result = await; $.get(url);
$("#test").html(result);
});
getAsync("http://www.sharpnrjs.com");
jsfiddle上的工作示例。
您可以从github下载该库。
当节点 0.11(带有具有 generators[2]的 v8 3.19 [1 ] )到达时,您可以使用Galaxy和如下代码。
然而,背后只有一面旗帜。ioJS 原生支持它们。
function* countLines(path) {
var names = yield fs.readdir(path);
var total = 0;
for (var i = 0; i < names.length; i++) {
var fullname = path + '/' + names[i];
if ((yield fs.stat(fullname)).isDirectory()) {
total += yield countLines(fullname);
} else {
var count = (yield fs.readFile(fullname, 'utf8')).split('\n').length;
console.log(fullname + ': ' + count);
total += count;
}
}
return total;
}
function* projectLineCounts() {
var total = 0;
total += yield countLines(__dirname + '/../examples');
total += yield countLines(__dirname + '/../lib');
total += yield countLines(__dirname + '/../test');
console.log('TOTAL: ' + total);
return total;
}
您可以使用 Jake Archibald 的内置 Generators、Promises 和一个小spawn() 函数在 Google Chrome 中启用 Experimental JS flag 来实现 async/await :
spawn(function*() { //this function is async
let story = yield getJSON('story.json'); //yield is like await
addHtmlToPage(story.heading);
});
或者,您可以使用:
对于不支持 ES6 的浏览器,有Facebook Regenerator。
为了完整性:我发现Saltarelle Compiler(它实际上将 C# 编译为 JavaScript)也支持 await/async。
如果你对 JavaScript 的 .NET 风格的异步编程感兴趣,你应该研究一下 Rx for JavaScript。Rx for JavaScrpt 是 Microsoft 的响应式框架的 JavaScript 端口。反应式框架描述为:
一个使用可观察集合和 LINQ 样式查询运算符组成异步和基于事件的程序的库。
你可以在这里下载 Rx for JavaScript
您可以阅读更多相关信息,包括此处的示例
你也可以使用 npm 在节点上安装它:
npm install rx
它适用于 jQuery 等库,但我不是 CoffeeScript 程序员,所以我不确定与该语言中的其他 JavaScript 库的互操作性有什么支持。
Javascript 在 ECMA 7 中提供了 async-await 特性。现在所有的异步函数都可以通过承诺它们并等待承诺解决来等待。大多数异步函数,如 DB 调用、API 调用、fs 和事件现在都在 Javascript 和 nodeJs 中返回 Promise。现在使用 async-await 代码更清晰、更易于理解和调试。
例子
function timeout(){
return new Promise( resolve => {
setTimeout(function(){
resolve(true);
}, 5000);
});
}
async function f(){
let result = await timeout();
}
有https://github.com/loveencounterflow/coffy-script尝试添加yield
到 CoffeeScript。CoffyScript 是非常新的,当我写这篇文章时,我正在思考require.extensions
作为一个全球性所带来的困难,以及我是否应该成为一个单独的扩展。也就是说,CoffyScript 确实有效,您会在我的 github 页面上找到许多示例,这些示例展示了如何使用suspend
、resume
和yield
.
鉴于yield
NodeJS 11.2 已经到来,我相信我们应该研究如何使用生成器/协程来使异步编程更容易接受。我已经放弃了承诺,与他们的经历并不那么愉快。再说一次,可能需要一段时间才能yield
在所有主要浏览器中可用。