当前位置: 首页 > news >正文

co.js - 让异步代码同步化

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

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

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

前端开发QQ群:377786580

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

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

  • ES6 - generator

  • ES6 - Promise

Generator 和 co

首先我们简单了解下 generator

// 定义一个 generators
function* foo(){
    yield console.log("bar");
    yield console.log("baz");
}

var g = foo();
g.next(); // prints "bar"
g.next(); // prints "baz"

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

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

var co = require('co');

function* foo() {
    yield Promise.resolve(console.log("bar"));
    yield Promise.resolve(console.log("baz"));
}

var co = require('co');
co(foo);

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

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

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

Callback

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

function ajax(q, callback) {
    var xhr = new XMLHttpRequest();
    xhr.onreadystatechange = function () {
        if (xhr.readyState == 4 && xhr.status == 200) {
            callback(xhr.responseText);
        }
    }
    xhr.open("GET", "query?q=" + q);
}

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

ajax('foo', function (foo) {
    console.log(foo);
    ajax('bar', function (bar) {
        console.log(bar);
    });
});

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

Promise

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

function ajax(q, callback) {
    // 使用 Promise 封装
    return new Promise(function (resolve) {
        var xhr = new XMLHttpRequest();
        xhr.onreadystatechange = function () {
            if (xhr.readyState == 4 && xhr.status == 200) {
                resolve(xhr.responseText);
            }
        }
        xhr.open("GET", "query?q=" + q);
    });
}

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

ajax('foo')
    .then(function (foo) {
        console.log(foo);
        return ajax('bar')
    })
    .then(function (bar) {
        console.log(bar);
    });

co

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

var co = require('co');

co(function* () {
    var foo = yield ajax('foo');
    console.log(foo);

    var bar = yield ajax('bar');
    console.log(bar);
});

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

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

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

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

前端开发QQ群:377786580

参考和引用

  • Promise.js

  • Github - TJ Holowaychuk - co.js

  • co 函数库的含义和用法

  • Thunk 函数的含义和用法

  • MDN - 迭代器和生成器

相关文章:

  • Xcode 7中http通信出现如下错误
  • nginx(1)
  • jquery的回调对象Callbacks详解
  • 【转】基于jquery,bootstrap数据验证插件bootstrapValidator 教程
  • Tomcat调优测试
  • Android学习笔记——ListView升级版--RecyclerView控件
  • ArcGIS中的WKID
  • 开始ruby
  • git 命令
  • 2014.8.27 CAD数据结构
  • 股指期货的交割日般是每月哪一天
  • Python学习文档指引
  • 身份验证无法登录
  • OpenStack 镜像制作之cloud-init
  • Ubuntu开启ssh服务(14.04)
  • [译]如何构建服务器端web组件,为何要构建?
  • Debian下无root权限使用Python访问Oracle
  • hadoop入门学习教程--DKHadoop完整安装步骤
  • iOS 系统授权开发
  • Java 23种设计模式 之单例模式 7种实现方式
  • JS数组方法汇总
  • webpack+react项目初体验——记录我的webpack环境配置
  • web标准化(下)
  • 道格拉斯-普克 抽稀算法 附javascript实现
  • 动态规划入门(以爬楼梯为例)
  • 复杂数据处理
  • 使用 @font-face
  • 微信小程序上拉加载:onReachBottom详解+设置触发距离
  • 移动端解决方案学习记录
  • 如何在 Intellij IDEA 更高效地将应用部署到容器服务 Kubernetes ...
  • ​queue --- 一个同步的队列类​
  • ​软考-高级-信息系统项目管理师教程 第四版【第19章-配置与变更管理-思维导图】​
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (力扣)1314.矩阵区域和
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (七)MySQL是如何将LRU链表的使用性能优化到极致的?
  • (四)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)
  • (算法)Travel Information Center
  • (转)IIS6 ASP 0251超过响应缓冲区限制错误的解决方法
  • (转)Linux下编译安装log4cxx
  • (转)关于如何学好游戏3D引擎编程的一些经验
  • (转)甲方乙方——赵民谈找工作
  • /*在DataTable中更新、删除数据*/
  • /使用匿名内部类来复写Handler当中的handlerMessage()方法
  • [ C++ ] STL---string类的模拟实现
  • [.NET]桃源网络硬盘 v7.4
  • [AIGC 大数据基础]hive浅谈
  • [ai笔记3] ai春晚观后感-谈谈ai与艺术
  • [android] 天气app布局练习
  • [C#]C# OpenVINO部署yolov8图像分类模型
  • [cocos creator]EditBox,editing-return事件,清空输入框
  • [HackMyVM]靶场Boxing
  • [hdu 1247]Hat’s Words [Trie 图]
  • [hdu 4552] 怪盗基德的挑战书
  • [IDF]聪明的小羊