koa學習筆記----callback,promise,generator

前言

Nodejs在0.11.x後開始支持generator,就是ES6中會正式定稿的規範。而後就有了基於此特性的koa框架,也就不少人所說的,以更優雅的方式進行流程控制。我的意見,若是沒有過多的回調,沒有大量的「惡魔金字塔」,仍是建議使用Express框架,更易上手,中間件選擇更多。接觸koa沒幾天,發現知識點略多略多,逐一擊破。git

Promise全局對象

一樣是0.11.x後開始原生支持的全局對象,規範與經常使用的Q模塊差別明顯,但接口更簡化,使用更方便。github

假設服務器端請求響應分爲三步,加載模板---讀取數據---渲染輸出。
模板以下(article.jade):數據庫

h3
  | #{title}
p
  | #{content}

數據以下(shuffle.json):express

{
  "title": "love story",
  "content": "No matter what the world will be, never give up for entire life"
}

業務代碼以下:json

fs.readFile(path.join(__dirname, 'views/article.jade'), function(err, data) {
  if (err) throw err;
  var template = data.toString();
  fs.readFile(path.join(__dirname, 'static/shuffle.json'), function(err, data) {
    if (err) throw err;
    var local = JSON.parse(data.toString());
    console.log(jade.compile(template)(local));
  });
});

經過兩層回調函數來實現,加載JSON數據可使用require方式來實現,此處僅爲說明狀況,由於實際狀況下,數據可能來自數據庫調用,或者第三方API請求。數組

這種業務處理方式下,模板與數據存在相互依賴,但不是流程上的順序並無嚴格要求,因此可以使用Promise,代碼實現以下:服務器

var jadeTemplate = new Promise(function(resolve, reject) {
  fs.readFile(path.join(__dirname, 'views/article.jade'), function(err, data) {
    if (err) {
      reject(err.message);
    } else {
      resolve(data.toString());
    }
  });
});

var localData = new Promise(function(resolve, reject) {
  fs.readFile(path.join(__dirname, 'static/shuffle.json'), function(err, data) {
    if (err) {
      reject(err.message);
    } else {
      resolve(JSON.parse(data.toString()));
    }
  });
});

Promise
  .all([jadeTemplate, localData])
  .then(function(value) {
    console.log(jade.compile(value[0])(value[1]));
  });

代碼量相對較多,可是效率更好,本機上測試,後者比前者快11ms,因此若有可能,採起後種。框架

關於generator

關於generator,所謂的生成器,概念上感受比較繞口,因此請自行百度。功能上看,就是外部操做控制函數內部代碼執行。舉一個簡單的例子以下:koa

// yield expression
var story = function *() {
  yield 'first step';
  console.log('first step');
  yield 'second step';
  console.log('second step');
};

var sequence = story();
sequence.next();
sequence.next();
sequence.next();

所謂外部操做控制內部代碼執行,能夠這麼理解。代碼從函數內部第‘0’行開始,外部的第一個next方法,開始向下執行,到碰到yield行中止執行。下次外部調用next方法,繼續向下執行,知道碰到yield時再次中止,直到內部代碼所有執行完畢或者碰到return something(通常不會使用)。每次next方法返回值爲一個對象:函數

{
  value: anything,
  done: boolean
}

done表示內部代碼是否所有執行完畢,即表明是否有進行下一次next方法調用的必要。value值爲yield後面跟着的表達式的計算值,能夠是字符串,數組,函數等基礎類型。

須要說明的是,生成器自己並非做爲流程控制的,可是能夠經過二次封裝,來實現流程控制,也就是co模塊。不折騰,不人生,週末看co模塊,好心塞。

聯繫方式

QQ:491229492
https://github.com/bornkiller

相關文章
相關標籤/搜索