Promise 깊이 들 어가 기 (3) - Promise 라 는 이름

7827 단어 jsNodePromise
Google 은 사용자 이름 을 통 해 사용자 정보 와 관심 자 를 찾 고 되 돌려 주 는 경우 가 많 습 니 다.보통 두 가지 방법 이 있다.
  • 외부 변 수 를 정의 합 니 다.
    var usergetUserByName('nswbmw')
      .then((_user) => {
        user = _user
        return getFollowersByUserId(user._id)
      })
      .then((followers) => {
        return {
          user,
          followers
        }
      })
  • 사용 폐쇄:
    getUserByName('nswbmw')
      .then((user) => {
        return getFollowersByUserId(user._id).then((followers) => {
          return {
            user,
            followers
          }
        })
      })
  • 두 가지 실현 은 모두 가능 하지만 그다지 아름 답지 않다.그래서 나 는 같은 층 의 then 인 자 는 이전의 모든 then 결과 의 역순 이라는 생각 이 들 었 다.코드 에 나타 나 는 것 은:
    Promise.resolve()
      .then(function () {
        return getUserByName('nswbmw')
      })
      .then(function (user) {
        return getFollowersByUserId(user._id)
      })
      .then((followers, user) => {
        return {
          user,
          followers
        }
      })

    세 번 째 then 의 인 자 는 앞의 두 then 결과 의 역순, 즉 followers 와 user 입 니 다.더 복잡 하 다. 예 를 들 어 promise 를 끼 워 넣 은 나 는 열거 하지 않 는 다. 이런 실현 의 요점 은 then 의 등급 을 어떻게 구분 하 느 냐 하 는 것 이다.appoint 의 실현 을 통 해 우 리 는 모든 then 이 새로운 promise 를 되 돌려 주 는 것 을 알 고 있 습 니 다. 이 로 인해 현재 then 이 이전에 얼마나 깊이 새 겨 진 promise 에서 왔 는 지 알 수 없습니다.그래서 이 생각 은 이 루어 질 수 없다.
    이름 Promise
    그 후에 저 는 위 보다 더 좋 은 해결 방법 을 생각 해 냈 습 니 다. 즉, Promise 라 는 이름 을 가 졌 습 니 다. 현재 then 의 첫 번 째 매개 변 수 는 아직도 이전 promise 의 반환 값 (즉 Promise / A + 규범 을 호 환 하 는 것) 이 고 뒤의 매개 변 수 는 의존 주입 을 사용 합 니 다.코드 에 나타 나 는 것 은:
    Promise.resolve()
      .then(function user() {
        return getUserByName('nswbmw')
      })
      .then(function followers(_, user) {
        return getFollowersByUserId(user._id)
      })
      .then((_, user, followers) => {
        return {
          user,
          followers
        }
      })

    위 에서 then 에 대한 리 셋 함수 이름 (예: user) 을 통 해 이 리 셋 함수 의 리 턴 값 을 promise 내부 변수 에 마 운 트 합 니 다 (예: values: {user: xxx). 부모 promise 의 values 를 하위 promise 에 전달 합 니 다.then 의 두 번 째 다음 매개 변 수 는 주입 에 의존 하여 주입 을 실현 합 니 다. 이것 이 바로 Promise 가 실현 하 는 기본 적 인 사고 입 니 다.Promise 구조 함수 의 인자, then 리 셋 함수 와 catch 리 셋 함수 에 이름 을 붙 일 수 있 습 니 다.
    그래서 저 는 appoint 가방 을 바탕 으로 named - appoint 가방 을 수정 하고 발 표 했 습 니 다.
    named - appoint 원리: promise 에 name 과 values 속성 을 추가 합 니 다. name 은 이 promise 구조 함수 의 인자, then 리 셋 함수 또는 catch 리 셋 함수 의 이름 을 가 져 옵 니 다. values 는 대상 으로 모든 조상 promise 의 name 과 value 를 저장 합 니 다.부모 promise 상태 가 바 뀌 었 을 때 부모 promise 의 value 와 values (this. values [this. name] = value) 를 설정 한 다음 values 를 하위 promise 의 values 로 복사 하여 순서대로 전달 합 니 다.다시 예 를 들 면:
    const assert = require('assert')const Promise = require('named-appoint')new Promise(function username(resolve, reject) {
      setTimeout(() => {
        resolve('nswbmw')
      })}).then(function user(_, username) {
      assert(_ === 'nswbmw')
      assert(username === 'nswbmw')
      return {
        name: 'nswbmw',
        age: '17'
      }}).then(function followers(_, username, user) {
      assert.deepEqual(_, { name: 'nswbmw', age: '17' })
      assert(username === 'nswbmw')
      assert.deepEqual(user, { name: 'nswbmw', age: '17' })
      return [
        {
          name: 'zhangsan',
          age: '17'
        },
        {
          name: 'lisi',
          age: '18'
        }
      ]}).then((_, user, followers, username) => {
      assert.deepEqual(_, [ { name: 'zhangsan', age: '17' }, { name: 'lisi', age: '18' } ])
      assert(username === 'nswbmw')
      assert.deepEqual(user, { name: 'nswbmw', age: '17' })
      assert.deepEqual(followers, [ { name: 'zhangsan', age: '17' }, { name: 'lisi', age: '18' } ])}).catch(console.error)

    분명히 Promise 라 는 전제 조건 은 같은 promise 체인 에 있다 는 것 이다.다음 코드:
    const assert = require('assert')const Promise = require('named-appoint')new Promise(function username(resolve, reject) {
      setTimeout(() => {
        resolve('nswbmw')
      })}).then(() => {
      return Promise.resolve()
        .then(function user(_, username) {
          assert(username === undefined)
          return {
            name: 'nswbmw',
            age: '17'
          }
        })}).then(function (_, username, user) {
      assert.deepEqual(_, { name: 'nswbmw', age: '17' })
      assert(username === 'nswbmw')
      assert(user === undefined)}).catch(console.error)

    마지막 then 인쇄 undefined 는 내부 에 새로운 promise 체인 분기 가 생 겼 기 때 문 입 니 다.
    결합 co 사용
    co 와 결합 하여 사용 하 는 것 은 아무런 변화 가 없다. 예 를 들 어:
    const Promise = require('named-appoint')const co = require('co')const promise = Promise.resolve()
      .then(function user() {
        return 'nswbmw'
      })
      .then(function followers() {
        return [{ name: 'zhangsan' }, { name: 'lisi' }]
      })
      .then((_, user, followers) => {
        return {
          user,
          followers
        }
      })co(function *() {
      console.log(yield promise)
      /*  { user: 'nswbmw',    followers: [ { name: 'zhangsan' }, { name: 'lisi' } ] }  */}).catch(console.error)

    겸사겸사 Promise / A + + 규범 을 제정 하 였 다.
    "까다 로 운" 오류 처리
    우리 계속 뇌 동 좀 하 자.Swift 에서 오류 처 리 는 다음 과 같 습 니 다:
    do {
      try getFollowers("nswbmw")
    } catch AccountError.No_User {
      print("No user")
    } catch AccountError.No_followers {
      print("No followers")
    } catch {
      print("Other error")
    }

    catch 는 특정한 이상 한 오류 만 캡 처 할 수 있 습 니 다. 이전 catch 가 캡 처 오류 가 없 으 면 마지막 catch 에 의 해 캡 처 됩 니 다.catch 리 셋 함수 JavaScript 라 는 이름 을 통 해 비슷 한 기능 을 수행 할 수 있 습 니 다. 저 는 appoint 를 바탕 으로 condition - appoint 패 키 지 를 수정 하고 발 표 했 습 니 다.예 를 들 어:
    var Promise = require('condition-appoint')Promise.reject(new TypeError('type error'))
      .catch(function SyntaxError(e) {
        console.error('SyntaxError: ', e)
      })
      .catch(function TypeError(e) {
        console.error('TypeError: ', e)
      })
      .catch(function (e) {
        console.error('default: ', e)
      })

    두 번 째 catch 에 포 착 됩 니 다. 인쇄:
    TypeError:  [TypeError: type error]

    수정:
    var Promise = require('condition-appoint')Promise.reject(new TypeError('type error'))
      .catch(function SyntaxError(e) {
        console.error('SyntaxError: ', e)
      })
      .catch(function ReferenceError(e) {
        console.error('ReferenceError: ', e)
      })
      .catch(function (e) {
        console.error('default: ', e)
      })

    세 번 째 catch 에 포 착 됩 니 다. 인쇄:
    default:  [TypeError: type error]

    대응 하 는 오류 catch 함수 가 없 기 때문에 익명 의 catch 에 의 해 캡 처 되 었 습 니 다.다시 수정:
    var Promise = require('condition-appoint')Promise.reject(new TypeError('type error'))
      .catch(function SyntaxError(e) {
        console.error('SyntaxError: ', e)
      })
      .catch(function (e) {
        console.error('default: ', e)
      })
      .catch(function TypeError(e) {
        console.error('TypeError: ', e)
      })

    두 번 째 catch 에 포 착 됩 니 다. 인쇄:
    default:  [TypeError: type error]

    익명 의 catch 방법 에 미리 잡 혔 기 때문이다.
    condition - appoint 실현 원 리 는 간단 합 니 다. appoint 의 then 에 3 줄 코드 를 추 가 했 습 니 다.
    Promise.prototype.then = function (onFulfilled, onRejected) {
      ...
      if (isFunction(onRejected) && this.state === REJECTED) {
        if (onRejected.name && ((this.value && this.value.name) !== onRejected.name)) {
          return this;
        }
      }
      ...};

    들 어 오 는 리 셋 함수 이름과 오류 이름 이 같 는 지 판단 합 니 다. 익명 함수 가 아니 라 같 지 않 으 면 return this 를 통 해 이 catch 문 구 를 건 너 뜁 니 다. 즉, 실제 값 이 관통 되 는 것 입 니 다.
    물론 condition - appoint 는 사용자 정의 오류 에 도 유효 합 니 다. 사용자 정의 오류 가 name 속성 을 설정 하면 됩 니 다.

    좋은 웹페이지 즐겨찾기