近期在全力開發我的網站,而且又沉澱了一些先後端的技術。近期會頻繁更新。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