js code 의 속도 측정 사이트
위의 사이트에서 특정 js code 를 적고, 실행해서 소요시간을 측정할 수 있다.
특징
- 위의 방법을 이용해서 손쉬게 firefox / chromium 의 속도 비교를 할 수 있다.
- 다만 주의할점은 처음 수행할 때와 두번째 수행할 때의 속도가 다를 수 있다. 그러므로 여러번 해보고 나서 속도를 판단할 필요가 있다.
// saga.js
import { put, takeEvery, all } from 'redux-saga/effects'
const delay = (ms) => new Promise(res => setTimeout(res, ms))
export function* helloSaga() {
console.log('Hello Sagas!')
}
// ...
// Our worker Saga: will perform the async increment task
export function* incrementAsync() {
yield delay(1000)
yield put({ type: 'INCREMENT' })
}
// Our watcher Saga: spawn a new incrementAsync task on each INCREMENT_ASYNC
export function* watchIncrementAsync() {
yield takeEvery('INCREMENT_ASYNC', incrementAsync)
}
// notice how we now only export the rootSaga
// single entry point to start all Sagas at once
export default function* rootSaga() {
yield all([
helloSaga(),
watchIncrementAsync()
])
}
// main.js
import "babel-polyfill"
import React from 'react'
import ReactDOM from 'react-dom'
import { createStore, applyMiddleware } from 'redux'
import Counter from './Counter'
import reducer from './reducers'
//// default export 인 sagaMiddlewareFactory 를 createSagaMiddleware 에 assign 한 것
import createSagaMiddleware from 'redux-saga'
// import { rootSaga } from './sagas'
import rootSaga from './sagas'
// const store = createStore(reducer)
const sagaMiddleware = createSagaMiddleware()
const store = createStore(
reducer,
applyMiddleware(sagaMiddleware)
)
sagaMiddleware.run(rootSaga)
const action = type => store.dispatch({type})
function render() {
ReactDOM.render(
<Counter
value={store.getState()}
onIncrement={() => action('INCREMENT')}
onDecrement={() => action('DECREMENT')}
onIncrementAsync={() => action('INCREMENT_ASYNC')} />,
document.getElementById('root')
)
}
render()
store.subscribe(render)
export default function applyMiddleware(...middlewares) { return createStore => (...args) => { // pass the createStore as an argument const store = createStore(...args) let dispatch = () => { throw new Error( 'Dispatching while constructing your middleware is not allowed. ' + 'Other middleware would not be applied to this dispatch.' ) } const middlewareAPI = { getState: store.getState, dispatch: (...args) => dispatch(...args) } // 기존의 dispatch 에 middleware 를 추가해서 dispatch 를 새롭게 만든다. const chain = middlewares.map(middleware => middleware(middlewareAPI)) dispatch = compose(...chain)(store.dispatch) return { ...store, dispatch } } } ... export default function createStore(reducer, preloadedState, enhancer) { ... if (typeof enhancer !== 'undefined') { if (typeof enhancer !== 'function') { throw new Error('Expected the enhancer to be a function.') } return enhancer(createStore)(reducer, preloadedState) } ... }
proc(env, iterator, context, effectId, getMetaInfo(saga), /* isRoot */ true, noop)
// saga.js
export default function* rootSaga() {
yield all([
helloSaga(),
watchIncrementAsync()
])
}
...
// runSaga.js function runSaga(_ref, saga) { ... var iterator = saga.apply(void 0, args); ... return immediately(function () { var task = proc(env, iterator, context, effectId, __chunk_1.getMetaInfo(saga), /* isRoot */ true, __chunk_1.noop); if (sagaMonitor) { sagaMonitor.effectResolved(effectId, task); } return task; }); }
function proc(env, iterator, parentContext, parentEffectId, meta, isRoot, cont) { if (iterator[__chunk_1.asyncIteratorSymbol]) { throw new Error("redux-saga doesn't support async generators, please use only regular ones"); } ... next(); // then return the task descriptor to the caller return task; /** * This is the generator driver * It's a recursive async/continuation function which calls itself * until the generator terminates or throws * @param {internal commands(TASK_CANCEL | TERMINATE) | any} arg - value, generator will be resumed with. * @param {boolean} isErr - the flag shows if effect finished with an error * * receives either (command | effect result, false) or (any thrown thing, true) */ function next(arg, isErr) { try { var result; if (isErr) { result = iterator.throw(arg); // user handled the error, we can clear bookkept values clear(); } else if (__chunk_1.shouldCancel(arg)) { /** getting TASK_CANCEL automatically cancels the main task We can get this value here - By cancelling the parent task manually - By joining a Cancelled task **/ ... } else if (__chunk_1.shouldTerminate(arg)) { // We get TERMINATE flag, i.e. by taking from a channel that ended using `take` (and not `takem` used to trap End of channels) ... } else { result = iterator.next(arg); } ... } catch (error) { if (mainTask.status === CANCELLED) { throw error; } mainTask.status = ABORTED; mainTask.cont(error, true); } } ... }
yield takeEvery('INCREMENT_ASYNC', incrementAsync)
간단히 이야기 하면, await/async 를 사용하게 해주는 것이라 보면 된다.
아래 글을 읽으면 자세한 이야기를 알 수 있다.
const crypto = require('crypto'); const hmac = crypto.createHmac('sha256', 'a secret'); hmac.update('some data to hash'); console.log(hmac.digest('hex'));
const ccursor = Database.connection('cocktail') .raw( `SELECT * FROM point AS t1 WHERE t1.id !='tester' ORDER BY id ASC` ).stream() const prom = new Promise((resolve, reject)=>{ Logger.error('test2'); ccursor.on('data', (row)=>{ Logger.info('test-data'); }) ccursor.on('end', () => { Logger.info('test-data'); resolve() }) ccursor.on('error', (param1) => { Logger.error('test-error : ' + param1); reject() }) }); await prom.then((val)=>{ Logger.info('test-resolve'); }).catch((val)=>{ Logger.error('test-reject'); });
Logger.info('test-data');
가 계속 실행되다가 끝날때 Logger.info('test-data');
가 실행될 것이다.const prom = new Promise((resolve, reject)=>{
const ccursor =
Database.connection('cocktail')
.raw(
`SELECT * FROM g5_point AS t1 WHERE t1.mb_id !='admin'
ORDER BY po_id ASC`
).stream();
ccursor.on('data', (row)=>{
Logger.error('test-data');
})
ccursor.on('end', () => {
Logger.error('test-end');
resolve()
})
ccursor.on('error', (param1) => {
Logger.error('test-error : ' + param1);
reject()
})
});
await prom.then((val)=>{
Logger.error('test-resolve');
}).catch((val)=>{
Logger.error('test-reject');
});
const prom = new Promise(async (resolve, reject)=>{ const ccursor = Database.connection('cocktail') .raw( `SELECT * FROM g5_point AS t1 WHERE t1.mb_id !='admin' ORDER BY po_id ASC` ).stream(); ccursor.on('data', async (row)=>{ Logger.error('test-data'); }) ccursor.on('end', async () => { Logger.error('test-end'); resolve() }) ccursor.on('error', async (param1) => { Logger.error('test-error : ' + param1); reject() }) }); await prom.then((val)=>{ Logger.error('test-resolve'); }).catch((val)=>{ Logger.error('test-reject'); });