JS Promise는 모나딕입니다. 예상한 방식이 아닙니다.

이들은 주로 Promise<NonPromiseType> 에 적용됩니다. 일부 속성은 중첩된 약속의 "언래핑"으로 인해 유지되지 않습니다.

FP 정의



함수형 프로그래밍 정의에 따라 필요한 것은 다음과 같습니다.
  • 유형 생성자: Promise<T> for any T
  • unit/형 변환기: Promise.resolve(value)
  • abind/합성기: Promise#then
  • 은 바인드(즉, unit(x) >>= f <=> f x)의 동일성을 남겨둔 단위를 갖는다: Promise.resolve(x).then(f)f(x)와 기능적으로 동일하다
  • unit 바인드의 올바른 동일성(즉, p >>= unit <=> p): myPromise.then(Promise.resolve)myPromise와 기능적으로 동일합니다.
  • bind는 연관적입니다(즉, ma >>= λx → (f(x) >>= g <=> (ma >>= f) >>= g ): promise.then(x => f(x).then(g))promise.then(f).then(g)와 기능적으로 동일합니다.

  • 따라서 우리는 <Promise, Promise.resolve, Promise#then>가 모나드임을 증명했습니다.

    그것이 차단하는 곳



    JS 약속에는 우리가 가진 모든 대안(예: jQuery의 지연) 대신 실행 가능하게 만드는 멋진 트릭이 있습니다.

    예를 들어, Promise.resolve(2).then(x => Promise.resolve(x * x)Promise<int>이지 Promise<Promise<int>>가 아닙니다. 이것을 보는 두 가지 방법이 있습니다.
  • 중첩된 약속은 유형으로 존재할 수 없습니다
  • .
  • 중첩된 약속은 중첩되지 않은 등가물에 대한 별칭입니다
  • .

    위 증명의 문제점은 다음과 같습니다.

    const x = Promise.resolve(2);
    const f = px => px.then(x => x * 2);
    
    f(x) !== Promise.resolve(x).then(f);
    

    Promise#then는 약속이 아닌 입력으로 값을 받는 연속이기 때문에 약속에 대한 약속의 왼쪽 IDunit를 보유할 수 없습니다. 값에 대한 약속의 왼쪽 ID만 보유할 수 있습니다. Promise#thenmapflatMap의 역할을 하기 때문입니다.

    분명히 이것은 당신이 Promise 모나딕을 고려한다면 이것이 당신을 물릴 유일한 상황입니다. 그렇지 않으면 당신은 그것들을 그렇게 취급하고 비 비동기/대기 코드를 적절하고 깨끗한 약속 기반 코드로 다시 작성하기 시작할 수 있습니다.

    promise.then(x => {
     return fetch(x).then(f);
    });
    
    // <=>
    
    promise
      .then(fetch)
      .then(f);
    

    좋은 웹페이지 즐겨찾기