Функция process.nextTick() помещается в начало очереди следующего цикла event loop и должна называться process.sendThisToTheStartOfTheQueue().
А setImmediate() помещается в конец очереди следующего цикла event loop и должна называться sendThisToTheEndOfTheQueue().
вторник, 30 января 2018 г.
четверг, 23 ноября 2017 г.
Redux Очень короткая шпаргалка
import {createStore, combineReducers, applyMiddleware} from 'redux';
// Counter
var counterActionType = {
'UP': 'UP'
};
function couterActionCreator (value) {
return {
type: counterActionType.UP,
value: value
};
}
function counterReducer (state, action) {
if (state === undefined) {state = {counter: 0};}
switch (action.type) {
case counterActionType.UP: return Object.assign({}, state, {counter: state.counter + action.value});
default: return state;
}
}
// Time
var timeActionType = {
'UPDATE': 'UPDATE'
};
function timeActionCreator (value) {
return {
type: timeActionType.UPDATE,
value: value
};
}
function timeReducer (state, action) {
if (state === undefined) {state = {time: new Date()};}
switch (action.type) {
case timeActionType.UPDATE: return Object.assign({}, state, {time: new Date(state.time.getTime() + action.value)});
default: return state;
}
}
var rootReducer = combineReducers({
counterObject: counterReducer,
timeObject: timeReducer
});
var initialState = {
counterObject: {counter: 2},
timeObject: {time: new Date()}
};
var store = createStore(rootReducer, initialState, applyMiddleware(/* createLogger(), thunkMiddleware */));
var unsubscribeStore = store.subscribe(function storeChangeListener () {
console.log(store.getState());
});
console.log(store.getState().counterObject.counter);
store.dispatch(couterActionCreator(1));
console.log(store.getState().counterObject.counter);
unsubscribeStore();
store.dispatch(couterActionCreator(1));
console.log(store.getState().counterObject.counter);
store.dispatch(timeActionCreator(1000000));
console.log(store.getState().timeObject.time);
// Counter
var counterActionType = {
'UP': 'UP'
};
function couterActionCreator (value) {
return {
type: counterActionType.UP,
value: value
};
}
function counterReducer (state, action) {
if (state === undefined) {state = {counter: 0};}
switch (action.type) {
case counterActionType.UP: return Object.assign({}, state, {counter: state.counter + action.value});
default: return state;
}
}
// Time
var timeActionType = {
'UPDATE': 'UPDATE'
};
function timeActionCreator (value) {
return {
type: timeActionType.UPDATE,
value: value
};
}
function timeReducer (state, action) {
if (state === undefined) {state = {time: new Date()};}
switch (action.type) {
case timeActionType.UPDATE: return Object.assign({}, state, {time: new Date(state.time.getTime() + action.value)});
default: return state;
}
}
var rootReducer = combineReducers({
counterObject: counterReducer,
timeObject: timeReducer
});
var initialState = {
counterObject: {counter: 2},
timeObject: {time: new Date()}
};
var store = createStore(rootReducer, initialState, applyMiddleware(/* createLogger(), thunkMiddleware */));
var unsubscribeStore = store.subscribe(function storeChangeListener () {
console.log(store.getState());
});
console.log(store.getState().counterObject.counter);
store.dispatch(couterActionCreator(1));
console.log(store.getState().counterObject.counter);
unsubscribeStore();
store.dispatch(couterActionCreator(1));
console.log(store.getState().counterObject.counter);
store.dispatch(timeActionCreator(1000000));
console.log(store.getState().timeObject.time);
среда, 22 ноября 2017 г.
React Очень короткая шпаргалка
import React, {Component} from 'react';
import ReactDOM from 'react-dom';
class Time extends Component {
// Actions
handleCounterUp () {
this.setState(Object.assign({}, this.state, {counter: this.state.counter + 1}));
}
handleInputChange (event) {
this.setState(Object.assign({}, this.state, {value: event.target.value.toUpperCase()}));
}
handleSubmitForm (event) {
event.preventDefault();
alert('Value: ' + this.state.value);
}
// First render (only once)
constructor (props) {
super(props);
this.state = {
time: null,
counter: 0,
value: ''
};
this.handleCounterUp = this.handleCounterUp.bind(this);
this.handleInputChange = this.handleInputChange.bind(this);
this.handleSubmitForm = this.handleSubmitForm.bind(this);
}
// setState OK
componentWillMount () {
this.setState(Object.assign({}, this.state, {time: new Date()}));
}
render () {
return (
<div>
{/* Это комментарий */}
<p>
<span>пробелы</span>{' '}
<span>между тэгами</span>{' '}
<span>на разных строках</span>
</p>
<ul>
{
[1, 2, 3].map(
function (value, index) {
return <li key={index}>{value}</li>;
}
)
}
</ul>
<div ref="message">My message</div>
<div>{this.state.time.toString()}</div>
<div>{this.props.time.toString()}</div>
<div>{this.state.counter}</div>
<div onClick={this.handleCounterUp}>Counter up</div>
<form onSubmit={this.handleSubmitForm}>
<input type="text" value={this.state.value} onChange={this.handleInputChange} />
<input type="submit" value="Submit" />
</form>
</div>
);
}
componentDidMount () {
var self = this;
this.timeoutId = setTimeout(function () {
self.setState(Object.assign({}, self.state, {time: new Date()}));
}, 1000);
// Actions after we updated DOM
// Here we can use jQuery to manipulate the DOM
// $('input-id).val('');
console.log(this.refs.message.innerText);
}
// Unmount in the end
componentWillUnmount () {
clearTimout(this.timeoutId);
}
// Next Props change - setState OK
componentWillReceiveProps (nextProps) {
this.setState(Object.assign({}, this.state, {time: nextProps.time}));
}
// Props change or only Next State change
shouldComponentUpdate (nextProps, nextState) {
return this.state.time.getTime() !== nextProps.time.getTime();
}
// No setState
componentWillUpdate (nextProps, nextState) {
// Actions before we updated DOM
}
// Render and then
componentDidUpdate (prevProps, prevState) {
// Actions after we updated DOM
// Here we can use jQuery to manipulate the DOM
// $(this._ref.input).val(');
console.log(this.refs.message.innerText);
}
}
ReactDOM.render(<Time time={new Date(new Date().getTime() + 100000000)} />, document.getElementById('root'));
пятница, 27 октября 2017 г.
TypeScript Краткая шпаргалка
// Объявление переменных
var a: number = 1;
let b: number = 2;
const c: number = 3;
// Типы переменных
let an: any = 0;
let unusable: void = undefined; // Может иметь только значение undefined или null
let undef: undefined = undefined;
let nul: null = null;
let bool: boolean = true;
let num: number = 1;
let str: string = 'text';
let arr1: number[] = [1, 2, 3];
let arr2: Array<number> = [1, 2, 3];
let arr3: ReadonlyArray<number> = [1, 2, 3];
let tuple: [number, string] = [1, 'text'];
let matrix: number[][] = [[1, 2], [3, 4]];
let obj: {a?: number} = {a: 1};
let union: undefined | null | string | number = 'text';
enum Color {Red = 1, Green = 2, Blue = 3}
let enu: Color = Color.Red;
function func (a?: number, b?: string): void {
return;
}
function error (message: string = 'text'): never {
throw new Error(message);
}
let [first, second, ...rest] = [1, 2, 3, 4];
let {one, two}: {one: string, two: number} = {
one: 'text',
two: 1
};
// Приведение типов переменных
let someValue: any = 'this is a string';
let strLength1: number = (someValue as string).length;
let strLength2: number = (<string>someValue).length;
// Объявление функций
function func1 (a?: number, b?: string): void {
return;
}
const func2 = function (a?: number, b?: string): void {
return;
};
const func3 = (a?: number, b?: string): void => {
return;
};
const func4: (x: number, y: number) => number = function (x: number, y: number): number {
return x + y;
};
function func5 (): Fish | Bird {
// ...
}
// Перегрузка функции
function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x): any {
if (typeof x == "object") {
return Math.floor(Math.random() * x.length);
} else if (typeof x == "number") {
return {suit: suits[Math.floor(x / 13)], card: x % 13 };
}
}
// Объявление классов
abstract class Animal {
abstract makeSound(): void;
move(): void {
console.log('roaming the earth...');
}
}
class A extends B implements BInterface {
readonly numberOfLegs: number = 8;
private currentTime: Date;
protected name: string;
public h: number;
public constructor (h: number, public m: number) {
super(m, h);
}
public setTime (d: Date) {
this.currentTime = d;
}
private count = (a: number): void => {
super.count(a);
console.log(a);
}
private static say (b: string): string {
return b;
}
private _fullName: string;
get fullName(): string {
return this._fullName;
}
set fullName (newName: string) {
this._fullName = newName;
}
}
let a: A = new A(10, 20);
class Point {
x: number;
y: number;
}
interface Point3d extends Point {
z: number;
}
let point3d: Point3d = {x: 1, y: 2, z: 3};
// Объявление интерфейсов
interface IOne {
str?: string;
[index: number]: string;
func (a: number): number;
}
interface ITwo extends IOne {
readonly obj: {b: number};
[propName: string]: any;
new (hour: number, minute: number);
}
// Объявление дженериков
function identity<T> (arg: T): T {
return arg;
}
let output = identity<string>('myString');
let myIdentity: <T>(arg: T) => T = identity;
interface GenericIdentityFn {
<T>(arg: T): T;
}
let myIdentity: GenericIdentityFn = identity;
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function (x, y) {
return x + y;
};
function create<T> (c: {new(): T;}): T {
return new c();
}
interface NotEmpty<T> {
data: T;
}
let x: NotEmpty<number>;
let y: NotEmpty<string>;
function extend<T, U> (first: T, second: U): T & U {
let result = <T & U>{};
for (let id in first) {
(<any>result)[id] = (<any>first)[id];
}
for (let id in second) {
if (!result.hasOwnProperty(id)) {
(<any>result)[id] = (<any>second)[id];
}
}
return result;
}
function pluck<T, K extends keyof T> (o: T, names: K[]): T[K][] {
return names.map(n => o[n]);
}
// Объявление типов
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
function getName(n: NameOrResolver): Name {
if (typeof n === 'string') {
return n;
} else {
return n();
}
}
type Easing = "ease-in" | "ease-out" | "ease-in-out";
type Shape = Square | Rectangle | Circle;
type Container<T> = {
value: T
};
type Tree<T> = {
value: T;
left: Tree<T>;
right: Tree<T>;
}
type LinkedList<T> = T & {next: LinkedList<T>};
type Proxy<T> = {
get(): T;
set(value: T): void;
}
type Proxify<T> = {
[P in keyof T]: Proxy<T[P]>;
}
function proxify<T>(o: T): Proxify<T> {
// ... wrap proxies ...
}
let proxyProps = proxify(props);
let personProps: keyof Person; // 'name' | 'age'
// Декларирование типов
type Alias = {num: number}
interface Interface {
num: number;
}
declare function aliased (arg: Alias): Alias;
declare function interfaced (arg: Interface): Interface;
declare function require (moduleName: string): any;
// Пространство имен
namespace Validation {
export class ZipCodeValidator implements StringValidator {
isAcceptable (s: string) {
return s.length === 5 ;
}
}
}
namespace Shapes {
export namespace Polygons {
export class Triangle { }
export class Square { }
}
}
declare namespace D3 {
export interface Selectors {
select: {
(selector: string): Selection;
(element: EventTarget): Selection;
};
}
export interface Event {
x: number;
y: number;
}
export interface Base extends Selectors {
event: Event;
}
}
declare var d3: D3.Base;
// Декораторы
function f () {
console.log("f(): evaluated");
return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
console.log("f(): called");
}
}
function g () {
console.log("g(): evaluated");
return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
console.log("g(): called");
}
}
class C {
@f()
@g()
method() {}
}
// f(): evaluated
// g(): evaluated
// g(): called
// f(): called
function classDecorator<T extends {new(...args:any[]):{}}>(constructor:T) {
return class extends constructor {
newProperty = "new property";
hello = "override";
}
}
@classDecorator
class Greeter {
property = "property";
hello: string;
constructor(m: string) {
this.hello = m;
}
}
console.log(new Greeter("world"));
class Point {
private _x: number;
private _y: number;
constructor(x: number, y: number) {
this._x = x;
this._y = y;
}
@configurable(false)
get x() { return this._x; }
@configurable(false)
get y() { return this._y; }
}
// Импорт
import "./my-module.js";
export * from "./ZipCodeValidator";
import * as validator from "./ZipCodeValidator";
import ZipCodeValidator from "./ZipCodeValidator";
import {ZipCodeValidator} from "./ZipCodeValidator";
import {ZipCodeValidator as ZCV} from "./ZipCodeValidator";
// Экспорт
declare let $: JQuery;
export default $;
export default "123";
export default function (s: string) {
return s.length === 5;
}
export default class ZipCodeValidator {
isAcceptable (s: string) {
return s.length === 5;
}
}
export ZipCodeValidator;
export interface StringValidator {
isAcceptable (s: string): boolean;
}
export class LettersOnlyValidator implements StringValidator {
isAcceptable (s: string) {
return lettersRegexp.test(s);
}
}
var a: number = 1;
let b: number = 2;
const c: number = 3;
// Типы переменных
let an: any = 0;
let unusable: void = undefined; // Может иметь только значение undefined или null
let undef: undefined = undefined;
let nul: null = null;
let bool: boolean = true;
let num: number = 1;
let str: string = 'text';
let arr1: number[] = [1, 2, 3];
let arr2: Array<number> = [1, 2, 3];
let arr3: ReadonlyArray<number> = [1, 2, 3];
let tuple: [number, string] = [1, 'text'];
let matrix: number[][] = [[1, 2], [3, 4]];
let obj: {a?: number} = {a: 1};
let union: undefined | null | string | number = 'text';
enum Color {Red = 1, Green = 2, Blue = 3}
let enu: Color = Color.Red;
function func (a?: number, b?: string): void {
return;
}
function error (message: string = 'text'): never {
throw new Error(message);
}
let [first, second, ...rest] = [1, 2, 3, 4];
let {one, two}: {one: string, two: number} = {
one: 'text',
two: 1
};
// Приведение типов переменных
let someValue: any = 'this is a string';
let strLength1: number = (someValue as string).length;
let strLength2: number = (<string>someValue).length;
// Объявление функций
function func1 (a?: number, b?: string): void {
return;
}
const func2 = function (a?: number, b?: string): void {
return;
};
const func3 = (a?: number, b?: string): void => {
return;
};
const func4: (x: number, y: number) => number = function (x: number, y: number): number {
return x + y;
};
function func5 (): Fish | Bird {
// ...
}
// Перегрузка функции
function pickCard(x: {suit: string; card: number; }[]): number;
function pickCard(x: number): {suit: string; card: number; };
function pickCard(x): any {
if (typeof x == "object") {
return Math.floor(Math.random() * x.length);
} else if (typeof x == "number") {
return {suit: suits[Math.floor(x / 13)], card: x % 13 };
}
}
// Объявление классов
abstract class Animal {
abstract makeSound(): void;
move(): void {
console.log('roaming the earth...');
}
}
class A extends B implements BInterface {
readonly numberOfLegs: number = 8;
private currentTime: Date;
protected name: string;
public h: number;
public constructor (h: number, public m: number) {
super(m, h);
}
public setTime (d: Date) {
this.currentTime = d;
}
private count = (a: number): void => {
super.count(a);
console.log(a);
}
private static say (b: string): string {
return b;
}
private _fullName: string;
get fullName(): string {
return this._fullName;
}
set fullName (newName: string) {
this._fullName = newName;
}
}
let a: A = new A(10, 20);
class Point {
x: number;
y: number;
}
interface Point3d extends Point {
z: number;
}
let point3d: Point3d = {x: 1, y: 2, z: 3};
// Объявление интерфейсов
interface IOne {
str?: string;
[index: number]: string;
func (a: number): number;
}
interface ITwo extends IOne {
readonly obj: {b: number};
[propName: string]: any;
new (hour: number, minute: number);
}
// Объявление дженериков
function identity<T> (arg: T): T {
return arg;
}
let output = identity<string>('myString');
let myIdentity: <T>(arg: T) => T = identity;
interface GenericIdentityFn {
<T>(arg: T): T;
}
let myIdentity: GenericIdentityFn = identity;
class GenericNumber<T> {
zeroValue: T;
add: (x: T, y: T) => T;
}
let myGenericNumber = new GenericNumber<number>();
myGenericNumber.zeroValue = 0;
myGenericNumber.add = function (x, y) {
return x + y;
};
function create<T> (c: {new(): T;}): T {
return new c();
}
interface NotEmpty<T> {
data: T;
}
let x: NotEmpty<number>;
let y: NotEmpty<string>;
function extend<T, U> (first: T, second: U): T & U {
let result = <T & U>{};
for (let id in first) {
(<any>result)[id] = (<any>first)[id];
}
for (let id in second) {
if (!result.hasOwnProperty(id)) {
(<any>result)[id] = (<any>second)[id];
}
}
return result;
}
function pluck<T, K extends keyof T> (o: T, names: K[]): T[K][] {
return names.map(n => o[n]);
}
// Объявление типов
type Name = string;
type NameResolver = () => string;
type NameOrResolver = Name | NameResolver;
function getName(n: NameOrResolver): Name {
if (typeof n === 'string') {
return n;
} else {
return n();
}
}
type Easing = "ease-in" | "ease-out" | "ease-in-out";
type Shape = Square | Rectangle | Circle;
type Container<T> = {
value: T
};
type Tree<T> = {
value: T;
left: Tree<T>;
right: Tree<T>;
}
type LinkedList<T> = T & {next: LinkedList<T>};
type Proxy<T> = {
get(): T;
set(value: T): void;
}
type Proxify<T> = {
[P in keyof T]: Proxy<T[P]>;
}
function proxify<T>(o: T): Proxify<T> {
// ... wrap proxies ...
}
let proxyProps = proxify(props);
let personProps: keyof Person; // 'name' | 'age'
// Декларирование типов
type Alias = {num: number}
interface Interface {
num: number;
}
declare function aliased (arg: Alias): Alias;
declare function interfaced (arg: Interface): Interface;
declare function require (moduleName: string): any;
// Пространство имен
namespace Validation {
export class ZipCodeValidator implements StringValidator {
isAcceptable (s: string) {
return s.length === 5 ;
}
}
}
namespace Shapes {
export namespace Polygons {
export class Triangle { }
export class Square { }
}
}
declare namespace D3 {
export interface Selectors {
select: {
(selector: string): Selection;
(element: EventTarget): Selection;
};
}
export interface Event {
x: number;
y: number;
}
export interface Base extends Selectors {
event: Event;
}
}
declare var d3: D3.Base;
// Декораторы
function f () {
console.log("f(): evaluated");
return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
console.log("f(): called");
}
}
function g () {
console.log("g(): evaluated");
return function (target, propertyKey: string, descriptor: PropertyDescriptor) {
console.log("g(): called");
}
}
class C {
@f()
@g()
method() {}
}
// f(): evaluated
// g(): evaluated
// g(): called
// f(): called
function classDecorator<T extends {new(...args:any[]):{}}>(constructor:T) {
return class extends constructor {
newProperty = "new property";
hello = "override";
}
}
@classDecorator
class Greeter {
property = "property";
hello: string;
constructor(m: string) {
this.hello = m;
}
}
console.log(new Greeter("world"));
class Point {
private _x: number;
private _y: number;
constructor(x: number, y: number) {
this._x = x;
this._y = y;
}
@configurable(false)
get x() { return this._x; }
@configurable(false)
get y() { return this._y; }
}
// Импорт
import "./my-module.js";
export * from "./ZipCodeValidator";
import * as validator from "./ZipCodeValidator";
import ZipCodeValidator from "./ZipCodeValidator";
import {ZipCodeValidator} from "./ZipCodeValidator";
import {ZipCodeValidator as ZCV} from "./ZipCodeValidator";
// Экспорт
declare let $: JQuery;
export default $;
export default "123";
export default function (s: string) {
return s.length === 5;
}
export default class ZipCodeValidator {
isAcceptable (s: string) {
return s.length === 5;
}
}
export ZipCodeValidator;
export interface StringValidator {
isAcceptable (s: string): boolean;
}
export class LettersOnlyValidator implements StringValidator {
isAcceptable (s: string) {
return lettersRegexp.test(s);
}
}
среда, 25 октября 2017 г.
React, Readux, React-Redux, Redux-Thunk краткая шпаргалка
import React from "react";
import {render} from "react-dom";
import {createStore, combineReducers, applyMiddleware} from "redux";
import thunk from "redux-thunk";
import {Provider, connect} from "react-redux";
const couterUpActionCreator = value => {
return {
type: "COUNTER_UP",
value: value
};
};
const counterDownActionCreator = value => {
return {
type: "COUNTER_DOWN",
value: value
};
};
const counterDownAsyncActionCreator = value => {
return dispatch => {
setTimeout(() => {
dispatch(counterDownActionCreator(value));
}, 1000);
};
};
const countReducer = (state = 0, action) => {
switch (action.type) {
case "COUNTER_UP": return state + action.value;
case "COUNTER_DOWN": return state - action.value;
default: return state;
}
};
const counterReducer = combineReducers({
count: countReducer
});
const rootReducer = combineReducers({
counter: counterReducer
});
const initialState = {
counter: {
count: 0
}
};
const store = createStore(rootReducer, initialState, applyMiddleware(thunk));
store.subscribe(() => {
console.log(store.getState());
});
class Counter extends React.Component {
styles = {
fontFamily: "sans-serif",
textAlign: "center"
}
constructor (props) {
super(props);
}
componentWillMount () {
console.log("Component Will Mount");
}
render () {
console.log('Render');
return (
<div style={this.styles}>
<div>{this.props.propsFromApp}</div>
<br />
<div onClick={this.handleUpClick}>^</div>
<div>{this.props.count}</div>
<div onClick={this.handleDownClick}>v</div>
</div>
);
}
componentDidMount () {
console.log("Component Did Mount");
}
componentWillReceiveProps (nextProps) {
console.log("Component Will Recieve Props");
}
shouldComponentUpdate (nextProps, nextState) {
console.log("Should Component Update");
if (this.props.propsFromApp !== nextProps) {
return true;
} else {
return false;
}
}
componentWillUpdate (nextProps, nextState) {
console.log("Component Will Update");
}
componentDidUpdate (prevProps, prevState) {
console.log("Component Did Update");
}
componentWillUnmount () {
console.log("Component Wiil Unmount");
}
handleUpClick = () => {
this.props.counterUp();
}
handleDownClick = () => {
this.props.counterDown();
}
}
const mapStateToProps = state => {
return {
count: state.counter.count
};
};
const mapDispatchToProps = dispatch => {
return {
counterUp: () => {
dispatch(couterUpActionCreator(1));
},
counterDown: () => {
dispatch(counterDownAsyncActionCreator(1));
}
};
};
const ConnectedCounter = connect(mapStateToProps, mapDispatchToProps)(Counter);
class App extends React.Component {
constructor (props) {
super(props);
this.state = {
propsFromApp: 0
};
}
render () {
return (
<div>
<div onClick={this.handleClick}>UPDATE STATE AND PROPS</div>
<ConnectedCounter propsFromApp={this.state.propsFromApp} />
</div>
);
}
handleClick = () => {
this.setState(
Object.assign(
{},
this.state,
{
propsFromApp: this.state.propsFromApp + 1
}
)
);
}
}
render(<Provider store={store}><App /></Provider>, document.getElementById("root"));
import {render} from "react-dom";
import {createStore, combineReducers, applyMiddleware} from "redux";
import thunk from "redux-thunk";
import {Provider, connect} from "react-redux";
const couterUpActionCreator = value => {
return {
type: "COUNTER_UP",
value: value
};
};
const counterDownActionCreator = value => {
return {
type: "COUNTER_DOWN",
value: value
};
};
const counterDownAsyncActionCreator = value => {
return dispatch => {
setTimeout(() => {
dispatch(counterDownActionCreator(value));
}, 1000);
};
};
const countReducer = (state = 0, action) => {
switch (action.type) {
case "COUNTER_UP": return state + action.value;
case "COUNTER_DOWN": return state - action.value;
default: return state;
}
};
const counterReducer = combineReducers({
count: countReducer
});
const rootReducer = combineReducers({
counter: counterReducer
});
const initialState = {
counter: {
count: 0
}
};
const store = createStore(rootReducer, initialState, applyMiddleware(thunk));
store.subscribe(() => {
console.log(store.getState());
});
class Counter extends React.Component {
styles = {
fontFamily: "sans-serif",
textAlign: "center"
}
constructor (props) {
super(props);
}
componentWillMount () {
console.log("Component Will Mount");
}
render () {
console.log('Render');
return (
<div style={this.styles}>
<div>{this.props.propsFromApp}</div>
<br />
<div onClick={this.handleUpClick}>^</div>
<div>{this.props.count}</div>
<div onClick={this.handleDownClick}>v</div>
</div>
);
}
componentDidMount () {
console.log("Component Did Mount");
}
componentWillReceiveProps (nextProps) {
console.log("Component Will Recieve Props");
}
shouldComponentUpdate (nextProps, nextState) {
console.log("Should Component Update");
if (this.props.propsFromApp !== nextProps) {
return true;
} else {
return false;
}
}
componentWillUpdate (nextProps, nextState) {
console.log("Component Will Update");
}
componentDidUpdate (prevProps, prevState) {
console.log("Component Did Update");
}
componentWillUnmount () {
console.log("Component Wiil Unmount");
}
handleUpClick = () => {
this.props.counterUp();
}
handleDownClick = () => {
this.props.counterDown();
}
}
const mapStateToProps = state => {
return {
count: state.counter.count
};
};
const mapDispatchToProps = dispatch => {
return {
counterUp: () => {
dispatch(couterUpActionCreator(1));
},
counterDown: () => {
dispatch(counterDownAsyncActionCreator(1));
}
};
};
const ConnectedCounter = connect(mapStateToProps, mapDispatchToProps)(Counter);
class App extends React.Component {
constructor (props) {
super(props);
this.state = {
propsFromApp: 0
};
}
render () {
return (
<div>
<div onClick={this.handleClick}>UPDATE STATE AND PROPS</div>
<ConnectedCounter propsFromApp={this.state.propsFromApp} />
</div>
);
}
handleClick = () => {
this.setState(
Object.assign(
{},
this.state,
{
propsFromApp: this.state.propsFromApp + 1
}
)
);
}
}
render(<Provider store={store}><App /></Provider>, document.getElementById("root"));
понедельник, 18 сентября 2017 г.
Node.js Cluster - особенности работы
const cluster = require('cluster')
, http = require('http')
, os = require('os');
const cpus = os.cpus().length;
// 3 Уровня создание кластера воркеров
// 1 уровень - уровень прослушивания всех событий для всех воркеров
cluster.on('message', function (worker, message, handle) {
console.log('All messages: ' + worker.id + ' | ' + message);
});
cluster.on('fork', function (worker) {
console.log('Worker ' + worker.id + ' forked.');
});
if (cluster.isMaster) {
// 2 уровень - уровень создания воркеров и уровень прослушивания событий для каждого конкретного воркера
for (let i = 0; i < cpus; i++) {
let worker = cluster.fork(); // Создание воркера
// Навешивание событий на конкретный созданный воркер
worker.on('listening', (address) => {
console.log(JSON.stringify(address));
});
worker.on('message', function (message) { // Получение сообщения из мастер-процесса кластера
console.log(message + ' master ' + process.pid);
worker.send('shutdown'); // Посылка сообщения из воркера в мастер-процесс кластера
worker.kill(); // Уничтожение текущего активного воркера
});
}
cluster.on('exit', function (worker, code, signal) {
console.log('Worker ' + worker.id + ' killed.');
});
} else if (cluster.isWorker) {
// 3 уровень - уровень кода воркера и посылки сообщений из мастер-процесса кластера текущему активному воркеру
// Код воркера
http.createServer(function (request, response) {
response.writeHead(200, 'OK');
response.end('HI ' + process.pid);
process.send('Done: ' + process.pid); // Посылка сообщения из мастер-процесса кластера текущему активному воркеру
}).listen(8000, '127.0.0.1', function () {
console.log('Server started ' + process.pid);
});
// Получение сообщения из текущего активного воркера мастер-процессом кластера
process.on('message', function (message) {
console.log('Message from worker: ' + message);
});
}
, http = require('http')
, os = require('os');
const cpus = os.cpus().length;
// 3 Уровня создание кластера воркеров
// 1 уровень - уровень прослушивания всех событий для всех воркеров
cluster.on('message', function (worker, message, handle) {
console.log('All messages: ' + worker.id + ' | ' + message);
});
cluster.on('fork', function (worker) {
console.log('Worker ' + worker.id + ' forked.');
});
if (cluster.isMaster) {
// 2 уровень - уровень создания воркеров и уровень прослушивания событий для каждого конкретного воркера
for (let i = 0; i < cpus; i++) {
let worker = cluster.fork(); // Создание воркера
// Навешивание событий на конкретный созданный воркер
worker.on('listening', (address) => {
console.log(JSON.stringify(address));
});
worker.on('message', function (message) { // Получение сообщения из мастер-процесса кластера
console.log(message + ' master ' + process.pid);
worker.send('shutdown'); // Посылка сообщения из воркера в мастер-процесс кластера
worker.kill(); // Уничтожение текущего активного воркера
});
}
cluster.on('exit', function (worker, code, signal) {
console.log('Worker ' + worker.id + ' killed.');
});
} else if (cluster.isWorker) {
// 3 уровень - уровень кода воркера и посылки сообщений из мастер-процесса кластера текущему активному воркеру
// Код воркера
http.createServer(function (request, response) {
response.writeHead(200, 'OK');
response.end('HI ' + process.pid);
process.send('Done: ' + process.pid); // Посылка сообщения из мастер-процесса кластера текущему активному воркеру
}).listen(8000, '127.0.0.1', function () {
console.log('Server started ' + process.pid);
});
// Получение сообщения из текущего активного воркера мастер-процессом кластера
process.on('message', function (message) {
console.log('Message from worker: ' + message);
});
}
среда, 13 сентября 2017 г.
Node.js UDP / Dgram Server and Client
const dgram = require('dgram');
// Server
const server = dgram.createSocket('udp4');
server.on('listening', function () {
console.log('Server listening: ' + JSON.stringify(server.address()));
});
server.on('message', function (message, rinfo) {
console.log('Server got message: "' + message + '" from: ' + rinfo.address + ':' + rinfo.port);
server.send(message, 0, rinfo.size, rinfo.port, rinfo.address, function (error) {
if (error) {throw error;}
server.close();
});
});
server.on('close', function () {
console.log('Server closed');
});
server.on('error', function (error) {
console.log('Server error: ' + error.stack);
server.close();
});
server.bind(8080, '127.0.0.1', function () {
console.log('Datagram server started at 127.0.0.1:8080');
});
// Client
const client = dgram.createSocket('udp4');
client.on('message', function (message, rinfo) {
console.log('Client got message: "' + message + '" from: ' + rinfo.address + ':' + rinfo.port);
client.close();
});
client.on('close', function () {
console.log('Client closed');
});
client.on('error', function (error) {
console.log('Client error: ' + error.stack);
client.close();
});
client.send([Buffer.from('Some bytes.'), Buffer.from(' And another bytes.')], 8080, '127.0.0.1', function (error) {
if (error) {throw error;}
});
// Server
const server = dgram.createSocket('udp4');
server.on('listening', function () {
console.log('Server listening: ' + JSON.stringify(server.address()));
});
server.on('message', function (message, rinfo) {
console.log('Server got message: "' + message + '" from: ' + rinfo.address + ':' + rinfo.port);
server.send(message, 0, rinfo.size, rinfo.port, rinfo.address, function (error) {
if (error) {throw error;}
server.close();
});
});
server.on('close', function () {
console.log('Server closed');
});
server.on('error', function (error) {
console.log('Server error: ' + error.stack);
server.close();
});
server.bind(8080, '127.0.0.1', function () {
console.log('Datagram server started at 127.0.0.1:8080');
});
// Client
const client = dgram.createSocket('udp4');
client.on('message', function (message, rinfo) {
console.log('Client got message: "' + message + '" from: ' + rinfo.address + ':' + rinfo.port);
client.close();
});
client.on('close', function () {
console.log('Client closed');
});
client.on('error', function (error) {
console.log('Client error: ' + error.stack);
client.close();
});
client.send([Buffer.from('Some bytes.'), Buffer.from(' And another bytes.')], 8080, '127.0.0.1', function (error) {
if (error) {throw error;}
});
Подписаться на:
Сообщения (Atom)