JavaScript 雲端開發研習營

Simon Sun

JSDC 2015 總召

Hackathon Taiwan 合作講師

Node.js Party 創辦團隊

Flow Controll

callback

step

async

promise

co

async await

Setup

npm install -g babel babel-cli 

callback.js

const function1 = function() {
    console.log('function1 done');
};

const function2 = function() {
    setTimeout(function(){
        console.log('function2 done');
    }, 3000);
};

const go = function() {
    function1();
    function2();
};

go();

callback.js

▶ babel-node callback.js
function1 done
function2 done

callback.js

const function1 = function() {
    console.log('function1 done');
};

const function2 = function() {
    setTimeout(function(){
        console.log('function2 done');
    }, 3000);
};

const go = function() {
    function2();
    function1();
};

go();

callback.js

▶ babel-node callback.js
function1 done
function2 done

callback.js

const function1 = function() {
    console.log('function1 done');
};

const function2 = function(callback) {
    setTimeout(function(){
        console.log('function2 done');
        return callback();
    }, 3000);
};

const go = function() {
    function2(function() {
        function1();
    });
};

go();

callback.js

▶ babel-node callback.js
function2 done
function1 done

所以寫到最後你的程式碼會變成這樣

foo(function() {
    bar(function() {
        wtf(function() {
            callbackHell(function() {
                .........
            });
        });
    });
});

不易閱讀

你的 code 會變成別人的地獄

不易維護

不夠直覺

你會忘記你做了什麼

接你 code 的人會想殺了你

step

An async control-flow library

That makes stepping through logic easy

step

npm install step 

step_demo.js

const step = require('step');

const function1 = function(){
    ....
};

const function2 = function(callback) {
    ....
};

step(
  function () {
    function2(this);
  },
  function () {
    function1();
  }
);
▶ babel-node step_demo.js
function2 done
function1 done

step_demo.js

step 也支持多併發處理唷

step

const step = require('step');

const function1 = function(){
    // do function1
};

const function2 = function(callback) {
    // do function2 after 3 second
};

const function3 = function(callback) {
    // do function3 after 1 second
};

step(
  function () {
    function2(this.parallel());
    function3(this.parallel());
  },
  function () {
    function1();
  }
);

stepParallel_demo.js

▶ babel-node stepParallel_demo.js 
function3 done
function2 done
function1 done

stepParallel_demo.js

async

Async utilities for node and the browser

前端後端都可以用唷 啾咪

async

npm install async 

asyncWaterfall.js

const async = require('async');

const function1 = function(callback){
    console.log('function1 done');
    return callback();
};

const function2 = function(callback) {
    setTimeout(function(){
        console.log('function2 done');
        return callback();
    }, 3000);
};

asyncWaterfall.js

async.waterfall([
    function(cb) {
        function2(cb);
    },
    function(cb) {
        function1(cb);
    }
],
function(err) {
    if(err) {
        console.log(err);
    }
    console.log('done');
});

asyncWaterfall.js

▶ babel-node asyncWaterfall.js 
function2 done
function1 done
done

async

多併發處理,小菜一碟

asyncParallel.js

const async = require('async');

const function1 = function(callback){
    console.log('function1 done');
    return callback();
};

const function2 = function(callback) {
    setTimeout(function(){
        console.log('function2 done');
        return callback();
    }, 3000);
};

const function3 = function(callback) {
    setTimeout(function(){
        console.log('function3 done');
        return callback();
    }, 1000);
};

asyncParallel.js

async.waterfall([
    function(cb) {
        async.parallel([
            function(next) {
              function2(next);
            },
            function(next) {
              function3(next);
            }
        ], cb);
    },
    function(err, cb) {
        function1(cb);
    }
],
function(err) {
    if(err) { console.log(err); }
    console.log('done');
});

asyncParallel.js

▶ babel-node asyncParallel.js 
function3 done
function2 done
function1 done
done

另外一個地獄

promise

你有寫過 jQuery 的 $.ajax 嗎?

jQuery $.ajax

$.ajax({
  url: "http://www.foo.bar"
})
.success(function(res){
    console.log(res.body);
})
.error(function(err) {
    console.log(err);
});

請把 promise 當作 $.ajax 寫

promise

npm install bluebird 

promise  callback 

promise  callback 

promise  callback 

callback

變成 

promise

promise

promise.promisify(callback)

promise_demo.js

const promise = require('bluebird');

const function1 = function(callback){
    console.log('function1 done');
    return callback();
};

const function2 = function(callback) {
    setTimeout(function(){
        console.log('function2 done');
        return callback();
    }, 3000);
};

const pfunction1 = promise.promisify(function1);
const pfunction2 = promise.promisify(function2);

promise_demo.js

promise.resolve(pfunction2())
.then(function() {
    return pfunction1();
})
.then(function() {
    console.log('done!!');
})
.error(function(err){
    console.log('error!!');
});

promise_demo.js

▶ babel-node promise_demo.js 
function2 done
function1 done
done!!

promise 多併發處理

promiseParallel_demo.js

const promise = require('bluebird');

const function1 = function(callback){
    console.log('function1 done');
    return callback();
};

const function2 = function(callback) {
    setTimeout(function(){
        console.log('function2 done');
        return callback();
    }, 3000);
};

const function3 = function(callback) {
    setTimeout(function(){
        console.log('function3 done');
        return callback();
    }, 1000);
};

promiseParallel_demo.js

const pfunction1 = promise.promisify(function1);
const pfunction2 = promise.promisify(function2);
const pfunction3 = promise.promisify(function3);

promise.all([
    pfunction3(),
    pfunction2()
])
.then(function() {
    return pfunction1();
})
.then(function() {
    console.log('done!!');
})
.error(function(error) {
    console.log('error!!');
});

promiseParallel_demo.js

▶ babel-node promiseParallel_demo.js
function3 done
function2 done
function1 done
done!!

why promise ?

跟 jQuery 很像

es6 原生用法

流程更為清楚簡潔

強大的錯誤控制

凡事都有一個 BUT

然後你又會發現你的 code ....

promise.resolve(foo())
.then(function(){
    return bar();
})
.then(function(){
    return wtf();
})
.then(function(){
    return promiseHell();
})
.then(function(){
    ....
})
.then(function(){
    ....
})
.error(function(error){
    console.log(error);
});

上帝關了一道門

就會開另一扇窗

強者我同事告訴我一個

「神器」

co

co

npm install co 

先來談談 yield 

再來談談 generator ?!!

嗯....下次好了

這就是 generator function

(先有個概念就好)

function*() {
    // this is generator function
}

co_demo.js

const promise = require('bluebird');
const co = require('co');

const function1 = function(callback){
    console.log('function1 done');
    return callback();
};

const function2 = function(callback) {
    setTimeout(function(){
        console.log('function2 done');
        return callback();
    }, 3000);
};

const pfunction1 = promise.promisify(function1);
const pfunction2 = promise.promisify(function2);
co(function*() {
    yield pfunction2();
    yield pfunction1();
})
.then(function() {
    console.log('done!!');
})
.catch(function(err) {
    console.log('error!!');
});

co_demo.js

co_parallel.js

const promise = require('bluebird');
const co = require('co');

const function1 = function(callback){
    console.log('function1 done');
    return callback();
};

const function2 = function(callback) {
    setTimeout(function(){
        console.log('function2 done');
        return callback();
    }, 3000);
};

const function3 = function(callback) {
    setTimeout(function(){
        console.log('function3 done');
        return callback();
    }, 1000);
};

co_parallel.js

const pfunction1 = promise.promisify(function1);
const pfunction2 = promise.promisify(function2);
const pfunction3 = promise.promisify(function3);

co(function*() {
    yield [
        pfunction2(),
        pfunction3()
    ];

    yield pfunction1();
})
.then(function() {
    console.log('done!!');
})
.catch(function(error) {
    console.log('error!!!');
});

co_parallel.js

▶ babel-node co_parallel.js
function3 done
function2 done
function1 done
done!!

why co ?

非同步中寫出同步的 code

易閱讀

易維護

程式碼減少很多

no hell, in heaven

async await

上次好樣有講師講過了

async await

const foo = async function(){
    let bar = await doFunctionBar();
    let wtf = await doFunctionWtf();
};

Authentication

淺談 Oauth

密碼加密機制

使用 passport

Oauth

Open Authorization 

Oauth

開放授權 ??!

Oauth

Oauth

允許使用者讓第三方應用存取該使用者在某一網站上儲存的私密的資源 balabalabalabala...

Oauth

簡單一點來說

Oauth

我可以拿 A 網站的帳號去 B 網站用

Oauth

我在 B 網站利用 Oauth 拿到「鑰匙」

B 網站拿這個「鑰匙」去跟 A 網站確認身份

我可以用 A 網站的身份去 B 網站使用

Oauth

「鑰匙」我們通常稱做 token

 

鑰匙是會過期的,要重新申請鑰匙

 

每個網站提供的鑰匙機制可能不一樣

密碼加密機制

不可逆

 

唯一性

hashPwd.js

const sha1 = require('sha1');

// 你傳入的密碼
const password = 'simonPWD';

// 加入一段固定字串
const hashString = '.$AWed(!';

// 加密
var hashPwd = sha1(hashString + password);

console.log(hashPwd);

hashPwd.js

▶ babel-node hashPwd.js
c221bf3692bc2e4377f71d6bea9f3691d2ff715b

passport

Simple, unobtrusive authentication for Node.js

passport

npm install passport

npm install passport-local (帳號密碼)

npm install passport-facebook (facebook)

......

......

有很多,可以慢慢找XD

passport

初始化 passport 專案

初始化 session 相關設定

經過 router 的 middleware

將資料綁定在 session

檢查進入時的 session

// passport 初始化
app.use(passport.initialize());

初始化 passport 專案

// passport 使用 session,所以你一定要裝 session 的 module
app.use(passport.session());

初始化 session 相關設定

passport.authenticate('local', {
    successRedirect: '/success',
    failureRedirect: '/fail'
})

經過 router 的 middleware

// 將你的 user 資料傳入 session
passport.serializeUser(function(user, done) {
    return done(null, user.name);
});

將資料綁定在 session

// 每次都會檢查 session
passport.deserializeUser(function(name, done) {
    return done(null, name);
});

檢查進入時的 session

passport

來看看完整的 demo 吧

passport

https://goo.gl/UJ7Aa3

passport

Why use gogs?         因為他有中文啊

passport

題外話......最近有點愛上土撥鼠了 >//////<

Q & A

JavaScript研討會

By simonsun2001

JavaScript研討會

  • 1,372