打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
闲谈异步调用“扁平”化
哦,代码……就把它们当成插图吧

随着 CPU 从单核变多核,软件从注重功能到注重体验,Web 从页面跳转方式到 Web2.0 的无刷新加载(AJAX),程序员越来越多的接触多线程和异步。而 Android 的主线程中不允许操作网络,更是将程序员们推向了异步的深渊。异步深渊产生的主要原因是回调,这在 nodejs 里尤其严重。

// [node.js]doFirstThing(function(err, data) {    doSecondThing(data, function(err, data) {        doThirdThing(data, function(err, data) {            // ... fall down        })    });});

为了逃离回调的深渊,大家开始想各种办法来把回调扁平化。

在 JavaScript 中,Promise(指该类方法而非某个库)成为众多解决方案的佼佼者,并成功被 ES6 采纳。

// [node.js]doFirstThing()    .then(doSecondThing)    .then(doThirdThing)    // .then(...) - continuous    .catch(function() {        // something wrong    });

而 C# 则通过 Task 和 ThreadPool 让异步编程变得容易。前面谈论的 C# 并行计算(Parallel 和 ParallelQuery) 就是基于 Task 的。不过使用 Task.ContinueWith()Parallel.ForEach() 的时候,就会觉得:这不就是 Promise 吗?

// [csharp]Task.Run(() => {    // do first thing and return a data    return "first";}).ContinueWith(task => {    // do second thing and return a data    return new []{ task.Result, "second" };}).ContinueWith(task => {    // do final thing    foreach (string s in task.Result) { Console.WriteLine(s); }}).Wait();

之后 C#5.0 又推出 async/await 方案,将异步代码写得像同步代码一样,由编译器来将 async/await 代码封装成异步 Task 方式,而不是由人工处理,这大大降低了写异步程序的门槛。

// [csharp]private async static Task Process() {    string first = await Task.Run(() => "first");    string[] all = await Task.Run(() => {        return new [] { first, "second" };    });        await(Task.Run(() => {        foreach (string s in all) { Console.WriteLine(s); }    }));}

JavaScript 程序员们一边在等着 ES7 的 async/await 特性,一边也没闲着,在 ES6 generator/yield 特性基础上开发了个 co 出来,提供了类似于 async/await 特性的异步编程方式。

// [node.js]var co = require("co");co(function*() {    var first = yield new Promise(function(resolve) {        setTimeout(function() {            resolve("first");        }, 100);    });    var all = yield new Promise(function(resolve) {        setTimeout(function() {            resolve([first, "second"])        }, 200);    })    console.log(all);});// [ 'first', 'second' ]

不过 co 程序写起来又要写 Generator,又要用 yeild,还常常要封装 Promise,代码仍然不够简洁。目前 async/await 已经在 TypeScript、Babel、Node 7.6+ 等环境中得到支持,使用 JavaScript 的 async/await 不仅能大大简化代码,还能降低逻辑思路的复杂度。

2018.1.18 更新,因为 async/await 早已进入实践阶段

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
异步陷阱之死锁篇
【5min+】帮我排个队,谢谢。await Task.Yield()
一文说通C#中的异步编程
C# 彻底搞懂async/await
C# 异步编程
JavaScript异步之从promise到await
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服