近期在全力开发个人网站,并且又沉淀了一些前后端的技术。近期会频繁更新。

这篇文章首发于我的个人网站:听说 - https://tasaid.com/,建议在我的个人网站阅读,拥有更好的阅读体验。

这篇文章与 博客园 和 Segmentfault 共享。

前端开发QQ群:377786580

coTJ 大神所编写的 JavaScript 异步解决方案的库,用于让异步的代码 "同步化"。

它构建在以下两个基础上,这篇文章不会详细讲解这 2 个知识点:

Generator 和 co

首先我们简单了解下 generator

  1. // 定义一个 generators
  2. function* foo(){
  3. yield console.log("bar");
  4. yield console.log("baz");
  5. }
  6. var g = foo();
  7. g.next(); // prints "bar"
  8. g.next(); // prints "baz"

简单来说,generator 实现了状态暂停/函数暂停 —— 通过 yield 关键字暂停函数,并返回当前函数的状态。

co 实现了 generator自动执行,我们使用 coPromise 修改上面的代码:

  1. var co = require('co');
  2. function* foo() {
  3. yield Promise.resolve(console.log("bar"));
  4. yield Promise.resolve(console.log("baz"));
  5. }
  6. var co = require('co');
  7. co(foo);

有人可能要说 "我自己写个循环执行 next 不也可以么? 为什么一个循环还要依赖一个库?"

co 有个使用条件:generator 函数的 yield 命令后面,只能是 Thunk 函数或 Promise 对象。

正是这个条件,让 co 强悍无比。

Callback

我们一步一步来看异步,首先使用 回调函数/Callback 的方式封装一个常见的 ajax 异步任务:

  1. function ajax(q, callback) {
  2. var xhr = new XMLHttpRequest();
  3. xhr.onreadystatechange = function () {
  4. if (xhr.readyState == 4 && xhr.status == 200) {
  5. callback(xhr.responseText);
  6. }
  7. }
  8. xhr.open("GET", "query?q=" + q);
  9. }

我们使用 回调函数 的方式连续发 2 条请求:

  1. ajax('foo', function (foo) {
  2. console.log(foo);
  3. ajax('bar', function (bar) {
  4. console.log(bar);
  5. });
  6. });

这是 js 中最典型的异步处理方案。

Promise

再使用 Promise 封装异步 ajax,让回调函数扁平化:

  1. function ajax(q, callback) {
  2. // 使用 Promise 封装
  3. return new Promise(function (resolve) {
  4. var xhr = new XMLHttpRequest();
  5. xhr.onreadystatechange = function () {
  6. if (xhr.readyState == 4 && xhr.status == 200) {
  7. resolve(xhr.responseText);
  8. }
  9. }
  10. xhr.open("GET", "query?q=" + q);
  11. });
  12. }

然后修改请求代码,扁平化异步代码:

  1. ajax('foo')
  2. .then(function (foo) {
  3. console.log(foo);
  4. return ajax('bar')
  5. })
  6. .then(function (bar) {
  7. console.log(bar);
  8. });

co

最后,让我们见一下 co 的强悍之处吧。我们使用 co.js 来修改请求代码:

  1. var co = require('co');
  2. co(function* () {
  3. var foo = yield ajax('foo');
  4. console.log(foo);
  5. var bar = yield ajax('bar');
  6. console.log(bar);
  7. });

最终我们的异步任务,在代码中同步化了。

对于异步代码来说,回调函数是最基础的方案,带来的弊端也显而易见。Promise 让代码扁平化,而 co 让代码同步化。

这篇文章首发于我的个人网站:听说 - https://tasaid.com/,建议在我的个人网站阅读,拥有更好的阅读体验。

这篇文章与 博客园 和 Segmentfault 共享。

前端开发QQ群:377786580

参考和引用

co.js - 让异步代码同步化的更多相关文章

  1. node.js的作用、回调、同步异步代码、事件循环

    http://www.nodeclass.com/articles/39274 一.node.js的作用 I/O的意义,(I/O是输入/输出的简写,如:键盘敲入文本,输入,屏幕上看到文本显示输出.鼠标 ...

  2. js 异步代码

    这段时间一直在用node.js做毕设的后台,所以需要一些异步代码操作,主要的异步方式有:Promise.Generator 和 async / await,但下面主要讲 Promise 和 async ...

  3. Node.js之异步流控制

    前言 在没有深度使用函数回调的经验的时候,去看这些内容还是有一点吃力的.由于Node.js独特的异步特性,才出现了"回调地狱"的问题,这篇文章中,我比较详细的记录了如何解决异步流问 ...

  4. 【译】深入理解python3.4中Asyncio库与Node.js的异步IO机制

    转载自http://xidui.github.io/2015/10/29/%E6%B7%B1%E5%85%A5%E7%90%86%E8%A7%A3python3-4-Asyncio%E5%BA%93% ...

  5. 利用python yielding创建协程将异步编程同步化

    转自:http://www.jackyshen.com/2015/05/21/async-operations-in-form-of-sync-programming-with-python-yiel ...

  6. 前端基本知识(四):JS的异步模式:1、回调函数;2、事件监听;3、观察者模式;4、promise对象

    JavaScript语言将任务的执行模式可以分成两种:同步(Synchronous)和异步(Asychronous). “同步模式”就是一个任务完成之后,后边跟着一个任务接着执行:程序的执行顺序和排列 ...

  7. js的异步和单线程

    最近,同事之间做技术分享的时候提到了一个问题"js的异步是另开一个线程吗?"当时为此争论不休.会后自己查阅了一些资料,对这个问题进行一个自我的分析与总结,有不同意见的希望可以赐教, ...

  8. 探秘JS的异步单线程

    对于通常的developer(特别是那些具备并行计算/多线程背景知识的developer)来讲,js的异步处理着实称得上诡异.而这个诡异从结果上讲,是由js的“单线程”这个特性所导致的. 我曾尝试用“ ...

  9. JS的异步世界

    前言 JS的异步由来已久,各种异步概念也早早堆在开发者面前.可现实代码中,仍然充斥了各种因异步顺序处理不当的bug,或因不好好思考,或因不了解真相.今天,就特来再次好好探索一番JS的异步世界. 01 ...

随机推荐

  1. PHP基础知识之变量

    定义: 变量用一个美元符号后面跟变量名来表示,如:$user 变量引用赋值: 引用赋值用一个&后面跟源变量名来表示,如:$copy=&$user(注:$bar = &(24 * ...

  2. c#之结构体

       struct是一种复合值类型,通常用来封装小型变量组,其中每个变量为结构的成员. C#中结构类型和类类型在语法上非常相似,他们都是一种数据结构,都可以包括数据成员和方法成员. 结构和类的区别: ...

  3. PHPCMS与UCenter整合要点

    要点一: PHPCMS不能直接与UCenter整合,而是要经过 PHPSSO 适配,因此应用主URL应是 http://phpcms_url/phpsso_server 这种模式的. 要点二: 因为 ...

  4. Java Socket

    什么是Socket Socket的概念很简单,它是网络上运行的两个程序间双向通讯的一端,既可以接收请求,也可以发送请求,利用它可以较为方便地编写网络上数据的传递. 所以简而言之,Socket就是进程通 ...

  5. MySQL 正则表达式

    介绍 正则表达式用来描述或者匹配符合规则的字符串.它的用法和like比较相似,但是它又比like更强大,能够实现一些很特殊的规则匹配:正则表达式需要使用REGEXP命令,匹配上返回"1&qu ...

  6. 《像计算机科学家一样思考Java》—— 读后总结

    本书属于入门级的Java书籍,与其他的向编程思想.核心技术不同的是,这本书不是按部就班的讲解java变成知识,而是随着语言的深入慢慢增加知识点. 这本书以一个语言开发者的角度,深入浅出的讲解了Java ...

  7. 详解 JavaScript的 call() 和 apply()

    定义 ECMAScript规范为所有函数都包含两个方法(这两个方法非继承而来), call 和 apply .这两个函数都是在特定的作用域中调用函数,能改变函数的作用域,实际上是改变函数体内 this ...

  8. Gyp语法规则参考 & 工具的使用

    转自:http://www.cnblogs.com/nanvann/p/3913880.html 翻译自 https://code.google.com/p/gyp/wiki/GypLanguageS ...

  9. salesforce 零基础学习(四十九)自定义列表分页之使用Pagination实现分页效果 ※※※

    上篇内容为Pagination基类的封装,此篇接上篇内容描述如何调用Pagination基类. 首先先创建一个sObject,起名Company info,此object字段信息如下: 为了国际化考虑 ...

  10. IDE:IDEA Commit Changes Dialog local changes refresh

    IDEA提交代码,一直卡着不动,显示:Commit Changes Dialog local changes refresh 修改方法为: go to settings - version contr ...