资讯专栏INFORMATION COLUMN

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

lanffy / 2196人阅读

摘要:前端开发群是大神所编写的异步解决方案的库,用于让异步的代码同步化。对于异步代码来说,回调函数是最基础的方案,带来的弊端也显而易见。让代码扁平化,而让代码同步化。

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

这篇文章首发于我的个人网站:听说 - 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 - 迭代器和生成器

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/80566.html

相关文章

  • ES6 Generator与异步同步书写

    摘要:返回值是一个对象,它的第一个属性是后面表达式的值或者的值第二个属性表示函数是否执行完成。真正的业务逻辑确实是用同步的方式写的。 开始前 我们从来没有停止过对javascript语言异步调用方式的改造,我们一直都想用像java那样同步的方式去写异步,尽管Promise可以让我们将异步回调添加到then方法中,但是这种调用方式仍然不那么优雅,es6 中新增加了generator,我们可以通...

    andycall 评论0 收藏0
  • co源码分析及其实践

    摘要:返回的结果是一个对象,类似于表示本次后面执行之后返回的结果。对象用于一个异步操作的最终完成或失败及其结果值的表示简单点说就是处理异步请求。源码分析主要脉络函数调用后,返回一个实例。参考链接解释对象的用法的源码及其用法 本文始发于我的个人博客,如需转载请注明出处。为了更好的阅读体验,可以直接进去我的个人博客看。 前言 知识储备 阅读本文需要对Generator和Promise有一个基本的...

    vincent_xyb 评论0 收藏0
  • 对Koa-middleware实现机制的分析

    摘要:现在我们从实现一个简易的方法开始探索其中的机制。其中内部的可以将上一个的返回值传递给外部。一言以蔽之实现了递归调用的方法。当执行到的中间件没有时并且返回的为时逆序执行。 本文发布在github.com/ssssyoki,欢迎star,issues共同交流。 Koa是基于Node.js的下一代web开发框架,相比Express更轻,源码只有几百行。与传统的中间件不同,在Koa 1.x中采...

    MageekChiu 评论0 收藏0
  • 深入探析koa之异步回调处理篇

    摘要:而之后,我们得到的是一个是一个对象,我们可以使用语句定义回调函数,函数的内容呢,则是将读取到的返回给并继续让从断点处执行。 在上一篇中我们梳理了koa当中中间件的洋葱模型执行原理,并实现了一个可以让洋葱模型自动跑起来的流程管理函数。这一篇,我们再来研究一下koa当中异步回调同步化写法的原理,同样的,我们也会实现一个管理函数,是的我们能够通过同步化的写法来写异步回调函数。 1. 回调金字...

    Drinkey 评论0 收藏0
  • dubbo源码解析(四十八)异步改造

    摘要:大揭秘异步化改造目标从源码的角度分析的新特性中对于异步化的改造原理。看源码解析四十六消费端发送请求过程讲到的十四的,在以前的逻辑会直接在方法中根据配置区分同步异步单向调用。改为关于可以参考源码解析十远程通信层的六。 2.7大揭秘——异步化改造 目标:从源码的角度分析2.7的新特性中对于异步化的改造原理。 前言 dubbo中提供了很多类型的协议,关于协议的系列可以查看下面的文章: du...

    lijinke666 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<