闲谈异步调用扁平化

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

随着 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 早已进入实践阶段



闲谈异步调用扁平化

原文地址:http://blog.51cto.com/jamesfancy/2062417

时间: 2024-10-14 10:35:51

闲谈异步调用扁平化的相关文章

从小小题目逐步走进 JavaScript 异步调用

问题 原题来自 @若泽[wangwenlin] 的提问. 可修改下面的 aa() 函数,目的是在一秒后用 console.log() 输出 want-value function aa() { setTimeout(function() { return "want-value"; }, 1000); } 但是,有额外要求: aa() 函数可以随意修改,但是不能有 console.log() 执行 console.log() 语句里不能有 setTimeout 包裹 解答 也许这是个面

你认为扁平化模式好还是树形结构好?

我认为对于小公司来说,扁平化的模式更好一些.由于小公司的规模比较小,公司内的员工不多,所需要的管理层次不多.扁平化模式的决策层和操作层之间的中间管理层次少,这可以使企业能够快速地将决策权延至企业生产.营销的最前线,从而为提高企业效率.而且由于公司规模小,管理部门之间的信息资源的交流.相互调用不会太多,这样可以是决策者集中更多的精力在企业的市场对策和企业发展的战略问题上. 对于大公司来说,树形结构会更好一些.大公司的规模比较大,所要做的项目比较多,如果一个人负责多个项目会造成项目完成效率不高.在树

FCC 中级算法题 数组扁平化

Steamroller 对嵌套的数组进行扁平化处理.你必须考虑到不同层级的嵌套. Array.isArray() 思路: (1)遍历arr,如果arr[i]是数组,就重新调用本函数继续循环,然后和新数组连接; (2)如果不是数组,就直接添加进新数组: 知识点: (1)Array.concat()方法用于合并两个或多个数组.此方法不会更改现有数组,而是返回一个新数组; (2)Array.push()方法将一个或多个元素添加到数组的末尾,并返回数组的新长度; (3)Array.isArray()用于

Docker扁平化网络设计与实现的方法步骤详解

研发背景 众所周知,Docker容器跨主机互访一直是一个问题,Docker官方为了避免网络上带来的诸多麻烦,故将跨主机网络开了比较大的口子,而由用户自己去实现.目前Docker跨主机的网络实现方案也有很多种,主要包括端口映射.ovs. fannel等. 但是这些方案都无法满足我们的需求:端口映射服务内的内网IP会映射成外网的IP,这样会给开发带来困惑,因为他们往往在跨网络交互时是不需要内网IP的:而ovs与fannel则是在基础网络协议上又包装了一层自定义协议,这样当网络流量大时,却又无端的增加

一位牛人的多线程和异步调用文章

转自小顾问原文 一位牛人的多线程和异步调用文章 首先申明:这篇文章不是我写的,我看到的一位牛人的,自己慢慢的消化了…… 摘要:本章讨论与智能客户端应用程序中多线程的使用有关的问题.为了最大限度地提高智能客户端应用程序的响应能力,需要仔细考虑如何和何时使用多线程.线程可以大大提高应用程序的可用性和性能,但是当您确定它们将如何与用户界面交互时,需要对其进行非常仔细的考虑. 线程是基本执行单元.单线程执行一系列应用程序指令,并且在应用程序中从头到尾都经由单一的逻辑路径.所有的应用程序都至少有一个线程,

cglib实现全配置的异步调用

参考cglib资料:http://www.tuicool.com/articles/IVfANr 实现逻辑为,对service类用cglib包装,让其调用方法改成异步调用,Future.线程池 对service方法的返回对象也用cglib包装,使其带有LazyLoad的功能 主要点:对cglib需要处理的类信息缓存,提高效率,通过lazyload,让用户不需要修改自己的代码,通过配置的方式就能进行异步化调用方法

Effective JavaScript Item 62 在异步调用中使用嵌套或者命名的回调函数

在一开始,理解异步程序的调用顺序会有些困难.比如,下面的程序中,starting会先被打印出来,然后才是finished: downloadAsync("file.txt", function(file) { console.log("finished"); }); console.log("starting"); downloadAsync方法在执行之后会立即返回,它只是为下载这个行为注册了一个回调函数而已. 由于JavaScript"

ios 统一设计,iOS6也玩扁平化

转:http://esoftmobile.com/2014/01/14/build-ios6-ios7-apps/ 前言 前段时间,苹果在它的开发者网站上放出了iOS系统安装比例,其中iOS7占到78%,iOS6占18%,剩余4%是iOS6以下版本.我们也借此机会将手上正在进行的两个项目都升级到支持iOS6及以上版本呢,有一种幸福来的太突然的赶脚,要知道在此之前我们都还在支持iOS4.3版本. 根据苹果另外一条消息,我们需要按照iOS7风格设计我们的Apps,至于iOS6系统,也没有必要为这部分

可视化设计之迷失扁平化风潮

编者注:编者注:本文源自Medium,本文发稿时原文在短短几天时间内已经获得了566个推荐,中文版本由天地会珠海分舵进行编译.文章对现在风靡全球的扁平化设计给予了深刻的思考.牡丹花确实是很美,但如果世界上都剩下了牡丹花了,你又会作何感想呢?这里让我们从著名乐队别安的<光辉岁月>的一句歌词开始:"缤纷色彩闪出的美丽,只因它没有,分开每种色彩-" 扁平化的盛行 伟大的UI设计扁平化盛行的2013-2014年间,设计师们将无数的像素都挥洒在扁平UI上面. 这段时间是可视化设计界的