继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

闲谈异步调用扁平化

零基础h5前端入门培训
关注TA
已关注
手记 301
粉丝 37
获赞 253

哦,代码……就把它们当成插图吧

随着 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,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP