ES6的generator. 方便編寫順序的異步代碼.

jopen 9年前發布 | 19K 次閱讀 ES6 JavaScript開發

gpipe

基于nodejs 0.11.14, ES6的generator. 方便編寫順序的異步代碼.

nodejs v0.11.14

使用 generator 異步代碼的例子:

var assert = require('assert'),
    gpipe = require('./lib/gpipe.js');

function fA(a, callback) {
    setTimeout(function () {
        callback(a, 'aaa');
    }, 1000);
}

function fB(b, callback) {
    setTimeout(function () {
        callback(b, 'bbb');
    }, 1000);
}

gpipe.scc(function* (ctrl) {
    var A = yield fA('a1', ctrl);
    assert.strictEqual(A[0], 'a1');  
    assert.strictEqual(A[1], 'aaa');  

    var B = yield fB('b1', ctrl);
    assert.strictEqual(B[0], 'b1');  
    assert.strictEqual(B[1], 'bbb');

    var C = yield gpipe.mcc(function* (ctrl) {
        yield fA('a2', ctrl('a'));
        yield fB('b2', ctrl('b'));
    }, ctrl);
    assert.strictEqual(C[0]['a'][0], 'a2');  
    assert.strictEqual(C[0]['a'][1], 'aaa');  
    assert.strictEqual(C[0]['b'][0], 'b2');
    assert.strictEqual(C[0]['b'][1], 'bbb');  
});

如你所見,異步代碼在形態上已經變成“同步”。

不止如此, gpipe提供兩個函數:

  • scc(generator[, callback]) scc串行代碼段,B的fB會等待A的fA,然后運行

  • mcc(generator[, callback]) mcc并行代碼段, C中的fA,fB同時運行, fB不會等待fA,全部完成后,通過callback發出

scc和mcc可以自由組合,我希望以此能搭配更靈活的代碼。

運行這段測試代碼,需要node v0.11.14 $ node --harmony test.js

有一些遺憾的是,我猜Joyent在v0.11加上了generator,竟然沒有添加解構賦值。所以,現在還沒法寫出:

var [err, data] = yield fs.readFile('/test', {encoding:'utf8'}, ctrl);
console.log(err);
console.log(data);

這樣的代碼, 而只能代之:

var it = yield fs.readFile('/test', {encoding:'utf8'}, ctrl);
console.log(it[0]);
console.log(it[1]);

it 是類似arguments的類數組。


一個更實際的例子:

使用fsmysql異步讀取數據

var fs = require('fs'),
    pool = require('mysql').createPool({ 
        host: "localhost",
        port: 8080,
        user: "root",
        password: "",
        database: "test",
        connectionLimit: 10
    }),
    gpipe = require('gpipe');

gpipe.scc(function* (ctrl) {
    var ro = yield fs.readFile('/test', { encoding:'utf8' }, ctrl);
    var err = ro[0];
    var data = ro[1];
    if (err) {
        throw err;
    }

    var wo = yield fs.writeFile('/new', data, { encoding:'utf8' }, ctrl);
    var err = wo[0];
    if (err) {
        throw err;
    }

    var mo = gpipe.mcc(function* (ctrl) {
        yield pool.query('SELECT * FROM employee', ctrl('employee'));
        yield pool.query('SELECT * FROM deparment', ctrl('deparment'));
        yield pool.query('SELECT * FROM order', ctrl('order'));
    }, ctrl);
    var employee = mo[0]['employee'];
    var deparment = mo[0]['deparment'];
    var order = mo[0]['order'];
}, function () {
    console.log('complete');
});

項目主頁:http://www.baiduhome.net/lib/view/home/1419300643859

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!