JavaScript - 비동기:동시성 프로그래밍(2)

박정호·2023년 1월 25일
0

JS

목록 보기
23/24
post-thumbnail

지연 평가 + Promise

지금까지 JS의 이터러블 객체를 중심으로 여러 함수들을 생성하였다.

예를 들어, map, filter, reduce를 뼈대로 응용해서 함수합성등을 통해 L.map ,takeAll, flatMap 등 응용 함수들을 만들었다.

하지만, L.map, map, take는 기본적으로 동기적으로 돌아가는 상황에서만 정상적인 동작을 보장한다.

따라서, reduce, pipe처럼 비동기상황에서도 동작할 수 있는 함수로 만들어보자.

💡 이터러블 함수들에 대하여...
👉 JavaScript - 지연성(1)
👉 JavaScript - 지연성(2)



Promise를 인자값으로 사용한 L.map

👎 비동기 처리를 하기 위한 Promise.resolve 를 사용할 경우, 정상적으로 동작하지 않는다.

go([Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)],
    L.map(a=>a+10),
    take(2),
    log
);

// 결과
//"[object Promise]10", "[object Promise]10"]

프로미스는 자바스크립트 비동기 처리에 사용되는 객체.

자바스크립트의 비동기 처리란 ‘특정 코드의 실행이 완료될 때까지 기다리지 않고 다음 코드를 먼저 수행하는 자바스크립트의 특성’을 의미.(참고)


L.map에서 Promise를 받도록 적용

👍 Promise로 값을 받을 수 있는 go1함수에 이터러블한 값을 넘겨 프로미스의 체인으로 연결하여 예정된 값으로 만들어준다.

const go1 = (a, f) => a instanceof Promise ? a.then(f) : f(a);

L.map = curry(function* (f, iter) {
    for (const a of iter) {
        yield go1(a,f);
    }
});
...
go([Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)],
    L.map(a=>a+10),
    take(2),
    log
);
//실행결과
//0: Promise {<fulfilled>: 11}
//1: Promise {<fulfilled>: 12}

take에서 Promise내부의 값 꺼내어 반환

기존 take 함수에서 currentValue(cur.value)Promise일 경우 내부의 값을 then을 통해 res Array에 넣어준 뒤 재귀적으로 다시 유명함수 recur()를 호출해 문제를 해결하고 있습니다.

const take = curry((l, iter) => {
    let res = [];
    iter = iter[Symbol.iterator]();

    return function recur() {
        let cur;
        while (!(cur = iter.next()).done) {
            const a = cur.value;
            if (a instanceof Promise) 
                return a.then(a => (res.push(a), res).length === l ? res : recur())
            res.push(a);
            if (res.length === l) return res;
        }
        return res;
    }();
});

go([Promise.resolve(1), Promise.resolve(2), Promise.resolve(3)],
    L.map(a=>a+10),
    take(2),
    log
);  //[11,12]


Kleisli Composition

profile
기록하여 기억하고, 계획하여 실천하자. will be a FE developer (HOME버튼을 클릭하여 Notion으로 놀러오세요!)

0개의 댓글