even more java script best practices
TRANSCRIPT
Even more JavaScriptbest practices
@GregWeng
NCU 2015/10/23
Today's lesson
Comment in JSDoc Style
Racing
Event queuing & Abortable Promise
ES6/7/8 & Babel
Homework review
JSDochttps://github.com/gitgrimbo/jsdoc3-examples
http://usejsdoc.org/
Generate (pretty) API documents for human
If you follow its comment format
Demo site of Gaia System app
http://alivedise.github.io/gaia-system-jsdoc/
Good first bugs for adding JSDoc comment
https://bugzilla.mozilla.org/show_bug.cgi?id=1170465
It is a good way to learn contribution
Racing & Abortable Promise
Racing
SystemBooting
passcode.enabled
Screen LockShows up
reading Lock withPasscode
return value
Booting Logo
Screen LockInitializing
~ 3 seconds
passcode.enabled
Screen LockShows up
reading Lock withPasscode
return value
Screen LockInitializing
~ 3 seconds
Racing
SystemBooting Booting Logo
Racing
Whenever there is a "guessing" about some async operations...
A racing is held
And the solution is not trivial...
Bug 1173284100+ comments & 1 month
passcode.enabled
Screen LockShows up
reading Lock withPasscode
return value
Screen LockInitializing
~ 3 seconds
Solution
SystemBooting Booting Logo
Freeze the slider
Event queueing & Abortable Promise
Public interfaces of JavaScript program components
JavaScript components usually use handlers as public interfaces among the user, server and other components
like to draw or to fire new events
private helper methods...
event handlers
server gateway
local data keeper
component usernative events
serversync
componentscustom events
Or racing may occur when two events and their async operations are performing
handler bar
handler foo
"handleEvent"
component
Async event handlers need a queue
async helper
sync helper
handling foo
waiting to handle bar
waiting to handle foo
waiting to handle foo
waiting to handle bar
event comes when thereis one being handled
Promise as the queue
Every handler will be queued by concating them with the 'then' method
handler bar
handler foo
"handleEvent"
component
Promise as the queue
async helper
sync helper
event comes when thereis one being handled
this.mainPromise = this.mainPromise.then( this.handlerBar.bind(this));
handling foo
waiting to handle bar
waiting to handle foo
Promise is not enoughwhen events are prioritized
Must not be queued: handle it immediately and clear all queued steps
handler bar
handler foo
"handleEvent"
component
Prioritized events
async helper
sync helper
handling bar
waiting to handle bar
waiting to handle foo
waiting to handle bar
waiting to handle bar
How to clear the queued steps?
handler bar
handler foo
"handleEvent"
component
Prioritized events
async helper
sync helper
waiting to handle bar
handling foo
waiting to handle bar
waiting to handle bar
waiting to handle bar
Promise/A+ spec doesn't provide any method to abort it...
Need to create a "Process" to wrap the original Promise
Throw an "Interrupt" customized error when prioritized event comes, and capture it later to silent the error console
handler bar
handler foo
"handleEvent"
component
Prioritized events with "Process"
async helper
sync helper
waiting to handle bar
handling foo
waiting to handle bar
waiting to handle bar
waiting to handle bar
Error: Interrupt
ES6/7/8 & Babel
import Utils from 'js/utils'
export default class {
constructor(id) {
this.id = id
this.queue = Promise.resolve()
}
handleEvent(event) {
this.queue = this.queue.then(() => {
return this.onEvent[event.type].bind(this)
}).catch((err) => {
this.onErrorOrInterrupt(err)
})
}
}
EcmaScript transpilerBabel
In the current front-end worldES6+ is becoming the mainstream
Homework review
Please do not test expression only:
About the test
it('will test some pure functions', function() { assert(2 === (1 + 1)); });
it('will test some pure functions', function() { var manager = new Manager() assert(2 === manager.pureAdd(1, 1)); });
//....
Manager.prototype.pureAdd = function(a, b) { return a + b; };
It is not necessary to bind then call it immediately
About the 'bind'
handleEvent(event) { .... case 'foo': this.onEventFoo.bind(this)() }
window.addEventListener('foo', this); // Bind `this` to the handleEvent //.... handleEvent(event) { .... case 'foo': this.onEventFoo() // `this` of 'handleEvent' is already bound }
The `then` method will pass the argument, and bound function can still be called as normal function, so:
About the Promise + 'bind'
.then(function(data) { this.foo(data); }.bind(this));
.then(this.foo.bind(this));
Please give it a clear naming convention to distinguish constructor and instance
Naming convention is important
var foo = function() {};var f = new foo();//....
var Foo = function() {};var foo = new Foo();//....
You are in trouble if your PR show some red lines like this and you can't explain that
And please comment on PR or using commits to indicate what issue you're addressing
Update: people who already commented on PRs
Quiz#1rockwyc992 : 吳易璋CaeserNieh : 聶順成rockwyc992 : 吳易璋Quiz#2jason1122g : 邱義傑bdsword : 蔣彥亭c910335 : 陳達仁Davisanity : 林唐正amm040341 : 蘇聖雅rueian : 黃瑞安w181496 : 黃詩凱Peter654q :莊侑穎bdsword : 蔣彥亭Quiz#3rueian : 黃瑞安c910335 : 陳達仁CrashedBboy : 吳承霖Sharknevercries : 李政遠jason1122g : 邱義傑