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