[Javascript] Generator 를 이용해서 Callback hell을 벗어나 보기....

Language/Typescript 2017.12.28 20:47


<<< co.ts >>>
//
// Module to help escape from callback-hell by using semi-coroutine(generator).
//

function co<E, T>(generator: GeneratorFunction,
        callback: (err: E, result: T) => void) {
    function *wrapper(resolve: any, reject: any) {
        let wrapperGenerator: Generator = yield;
        try {
            let result = yield* (<any>generator)(wrapperGenerator);
            resolve(result);
        } catch (e) {
            reject(e);
        }
    }

    new Promise<T>((resolve, reject) => {
        let w = wrapper(resolve, reject);
        w.next(); // run function
        w.next(w);
    }).then(r => {
        callback(<any>undefined, r);
    }, e => {
        callback(e, <any>undefined);
    });
}

export = co;


<< main.ts >>

import co = require('./co');


describe('co', function() {
    it('co success', done => {
        co<string, Array<Number>>(<any> function* (gen: Generator) {
            let path = new Array<Number>();
            path.push(10);
            setTimeout(() => {
                path.push(20);
                gen.next();
            }, 200);
            yield;
            path.push(30);
            return path;
        }, (err, result) => {
            assert.ok(undefined === err
                && 3 === result.length
                && result[0] === 10
                && result[1] === 20
                && result[2] === 30);
            done();
        });
    });

    it('co fails: throw in generator', done => {
        co<string, string>(<any> function* (gen: Generator) {
            setTimeout(() => {
            }, 200);
            if (gen) {
                throw 'error';
            }
            return 'hello';
        }, (err, result) => {
            assert.ok(undefined === result
                && 'error' === err);
            done();
        });
    });

    /*
     * This test gives unexpected error at mocha. But works well at normal environment.
     *
     *
     * (node:41022) UnhandledPromiseRejectionWarning: Unhandled promise rejection...
     * (node:41022) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated....
     * node_modules/mocha/lib/runner.js:690
     * err.uncaught = true;
     *            ^

     * TypeError: Cannot create property 'uncaught' on string 'error'
     *     at Runner.uncaught ...
     *     ...
     *

    it('co fails: Generator.throw', done => {
        let path = new Array<Number>();
        co<string, string>(<any> function* (gen: Generator) {
            setTimeout(() => {
                gen.throw!('error');
                path.push(10);
                return;
            }, 200);
            return 'done';
        }, (err, result) => {
            assert.ok(undefined === result
                && 'error' === err
                && 1 === path.length);
            done();
        });
    });
    */
});


Trackback 0 : Comment 0

[Essay] <기술적>으로 뛰어난 사람이 상대적으로 인정받지 못하는 이유

Essay/Software 2017.12.28 20:44

여기서 <뛰어난> 이란, 아~주 특출나게 뛰어난 경우가 아닌, 상위권 수준으로 뛰어난 사람을 뜻한다.

<뛰어난 사람>
* 기술적인 성과를 이루었다.
=> 대단한 일이 아니라고 생각한다. 왜나햐면, 자기 자신에 비추어 생각해 보면, 이건 그리 어려운 일이 아니였으므로...

<평범한 사람>
* 기술적인 성과를 이루었다.
=> 자기 자신에 비추어 봤을 때, 대단한 성과라고 생각하므로 적극 홍보/자랑 한다.

그런데, 보통, senior manager group은 기술의 세부적인 내용에 대한 이해가 부족하다.
그리고, 대부분의 경우, 성과를 판단하는 요소에, 실제 기술적인 성과는 상당히 많이 간략화 되기 때문에, 홍보/포장 이 많은 비중을 차지하게 된다.

물론, 기술 자체는 그 활용성이 없다면 의미가 없다. 하지만... 기술적인 성과는 차후 개선의 밑바탕이 될 수 있으므로, 여전히 중요하다.
-------------

극단적인 생각이긴 한데... 이런 모습이 조직에서 종종 보이는 것 같다.
다시 말하지만, 극단적이다. 그렇지만, "위와 같은 모습이 종종 보이더라..." 라는 것 자체도 언급할 가치가 있지 않을까?

Trackback 0 : Comment 0

[Javascript] Understanding 'Prototype' of Javascript

Language/Typescript 2017.12.28 20:38


< 좋은 link >
http://insanehong.kr/post/javascript-prototype/



< From: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new >

The new operator creates an instance of a user-defined object type or of one of the built-in object types that has a constructor function.

...

When the code new Foo(...) is executed, the following things happen:

A new object is created, inheriting from Foo.prototype.
The constructor function Foo is called with the specified arguments, and with this bound to the newly created object. new Foo is equivalent to new Foo(), i.e. if no argument list is specified, Foo is called without arguments.
The object returned by the constructor function becomes the result of the whole new expression. If the constructor function doesn't explicitly return an object, the object created in step 1 is used instead. (Normally constructors don't return a value, but they can choose to do so if they want to override the normal object creation process.)


< From: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/prototype >

...

Object.prototype.constructor
    Specifies the function that creates an object's prototype.

...


--------
즉, 'prototype' property는, 결국 'new' operation에서 object inherit을 위해 사용되는 reserved property이고, instance의 prototype chain은 [[Prototype]](de-facto __proto__) 에 의해 관리된다.

이상에서 다음을 알수(유추할수?) 있다.
- 'prototype' property 는 일반적인 object 이다. (*1)
    : constructor function을 가지는 단순한 object (javascript의 'new' operation protocol을 맞추기 위한 suger object 정도로 밖에 보이지 않는다.)
- 'prototype' property 는 'constructor' function을 가진 object에 한해서만 의미가 있다.
- [[Prototype]]은 'prototype' object 를 가리킨다.

=====================
확실한 이해를 위해 'new' operation의 동작을 확인해 보자.(Tested on console of Chrome-63)


> function A(name) {
    this.date = Date.now();
    this.x = 'Proto';
    this.name = name;
}
undefined

> a = new A('a')
A {date: 1514262817152, x: "Proto", name: "a"}

> b = new A('b')            <= date 값이 매번 달라진다.
A {date: 1514262824795, x: "Proto", name: "b"}

> A.prototype                <= constructor만을 가지는 아주 단순한 object
{constructor: ƒ}
    constructor: ƒ A(name)
    __proto__: Object        <= Object Prototype


> c = Object.create(A.prototype);    <= 단순하게 constructor를 상속하는 과정이라고 생각할 수도 있다.
A {}

> c.constructor('c')            <= Prototype의 constructor를 새롭게 생성된 object에 binding해서 수행한다. (Same with, c.__proto__.constructor.call(c, 'c'))
undefined                   Note: binding of 'this' keyworkd (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this)
                       Note: c.__proto__.constructor('c') <= 잘못된 수행. prototype object 자체를 더럽히게 된다.
> c.constructor === c.__proto__.constructor
true

> c
A {date: 1514262907466, x: "Proto", name: "c"}


Trackback 0 : Comment 0