近期在全力开发我的网站,而且又沉淀了一些先后端的技术。近期会频繁更新。javascript
这篇文章首发于个人我的网站:据说 - https://tasaid.com,建议在个人我的网站阅读,拥有更好的阅读体验。html
这篇文章与 博客园 和 Segmentfault 共享。前端
前端开发QQ群:377786580java
co 是 TJ 大神所编写的 JavaScript 异步解决方案的库,用于让异步的代码 "同步化"。git
它构建在如下两个基础上,这篇文章不会详细讲解这 2 个知识点:github
ES6 - generatorajax
首先咱们简单了解下 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
关键字暂停函数,并返回当前函数的状态。ide
co
实现了 generator
的 自动执行,咱们使用 co
和 Promise
修改上面的代码:
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
的方式封装一个常见的 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 封装异步 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.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