Workspace
  • Study Book
  • WEB Network HTTP etc
    • Performance Optimization
    • Performance Optimization
    • HTTP/2 & SPDY
    • WebSocket
    • HTTP Header
    • Cross-Origin Resource Sharing
    • JSON, XML, other format
  • Javascript
    • Promise
    • make API call
    • Web API
    • Common JS
    • AJAX
    • Event DOM and delegation
    • ES6 new features
    • special function
    • function API
  • React
    • class component
    • Example
    • Lifting functions/ state up
    • Hot Loader
    • Testing
    • New Features
    • Hook
    • Simple code
    • Life Cycle
  • CSS
    • Horizontal & Vertical Align
    • GPU Animation
    • transform-function
    • LVHA Pseudo-classes
    • Selector
    • How To CSS
  • HTML
  • Redux
  • NodeJS
    • File System
  • express
    • express questions
    • express mongodb
  • Restful API
  • MongoDB
  • Compare
  • Test
    • Jest
  • Deploy development
  • coding question
  • DevOps
  • Webpack
  • GraphQL
Powered by GitBook
On this page
  • Method:
  • Then() method
  • promise chain
  • Promise use observable module:
  • Implement promise all, resolve, reject, race
  • Promise all:
  • Race
  • Resolve
  • Reject
  • Then

Was this helpful?

  1. Javascript

Promise

PreviousJavascriptNextmake API call

Last updated 4 years ago

Was this helpful?

fullfill -> resolve, reject, eventual value/value. reason.

  • Promise represents the eventual completion of an async operation

  • It must be in one of these states

    • pending

      • initial state, not fulfilled or rejected

    • fulfilled

      • meaning that the operation completed successfully

    • rejected

      • meaning that the operation failed

  • It is guaranteed that a promise object will either succeed or fail

  • promise.all

    • returns a single promise that resolves when all of the promises in the argument have resolved or when the utterable argument contains no promises

  • create Promise example

Method:

Promise.all(iterable)Wait for all promises to be resolved, or for any to be rejected. If the returned promise resolves, it is resolved with an aggregating array of the values from the resolved promises in the same order as defined in the iterable of multiple promises.

Promise.race(iterable) Wait until any of the promises is resolved or rejected. If the returned promise resolves, it is resolved with the value of the first promise in the iterable that resolved. If it rejects, it is rejected with the reason from the first promise that was rejected.

Promise.reject(reason)

Promise.resolve(value)Returns a new Promise object that is resolved with the given value.

function asyncDoubble(n) {
    return new Promise((resolve, reject) => {
        if (typeof n === "number") {
            resolve(n * 2);
        } else {
            reject(new Error (n + "is not a number!"));
        }
    });
}
asyncDouble(3).then(
    data => console.log(data);
    error => console.log(error);
);

Then() method

promise.then(onFulfilled, onRejected)

onFulfilled and two function()

onFulfilled(a, []) : call after promise finished. the a is the return of promise

onRejected(a, []) : call after promise finished. the a is the reason of promise

Then can be called multiply times:

if resolve: onFulfilled call back one by one

if reject: onRejected call back one by one

promise chain

new Promise(function(resolve, reject) {

  setTimeout(() => resolve(1), 1000); // (*)

}).then(function(result) { // (**)

  alert(result); // 1
  return result * 2;

}).then(function(result) { // (***)

  alert(result); // 2
  return result * 2;

}).then(function(result) {

  alert(result); // 4
  return result * 2;

});

Promise use observable module:

class EventEmitter {
    constructor() {
        this.eventChannel = {};
    }
    on(event, callback) {
        this.eventChannel[event] ?
            this.eventChannel[event].push(callback) :
            this.eventChannel[event] = [callback]
    }
    emit(event, ...args) {
        this.eventChannel[event] && this.eventChannel[event].forEach(callback => callback(...args))
    }
    remove(event) {
        if (this.eventChannel[event]) {
            delete this.eventChannel[event]
        }
    }
    once(event, callback) {
        this.on(event, (...args) => {
            callback(...args);
            this.remove(event)
        })
    }
}

class Observer {
    constructor() {
        this.observerList = [];
    }
    subscribe(observer) {
        this.observerList.push(observer)
    }
    notifyAll(value) {
        this.observerList.forEach(observe => observe(value))
    }
}

Implement promise all, resolve, reject, race

class Promise {
 state = 'pending'
  value = null
  reason = null

  onFulfilledCallback = []
  onRejectedCallback = []

  constructor(executor) {
    if (typeof executor !== 'function') {
      throw TypeError('executor is not a function!')
    }

    this.resolve = this.resolve.bind(this)
    this.reject = this.reject.bind(this)

    executor(this.resolve, this.reject)
  }

  
  finally(callback) {
    return this.then(
      () => Promise.resolve(callback()),
      () => Promise.reject(callback()),
    )
  }
 
}

Promise all:

promises should be array of function

static all(promises) {
    if (!promises || typeof promises[Symbol.iterator] !== 'function') {
      throw TypeError(
        `${typeof promises} is not iterable (cannot read property Symbol(Symbol.iterator))`,
      )
    }

    let index = 0
    const res = []

    return new Promise((resolve, reject) => {
      const n = promises.length
      if (!n) return []
      function processPromise(value, i) {
        res[i] = value
        if (++index === n) resolve(res)
      }

      for (let i = 0; i < n; i++) {
        Promise.resolve(promises[i]).then(
          (value) => {
            processPromise(value, i)
          },
          (reason) => {
            reject(reason)
          },
        )
      }
    })
  }

Race

class Promise {
  static race(promises) {
    if (!promises || typeof promises[Symbol.iterator] !== 'function') {
      throw TypeError(
        `${typeof promises} is not iterable (cannot read property Symbol(Symbol.iterator))`,
      )
    }

    if (!promises.length) {
      throw Error('Promise.race need length')
    }

    return new Promise((resolve, reject) => {
      for (const promise of promises) {
        Promise.resolve(promise).then(
          (value) => {
            resolve(value)
          },
          (reason) => {
            reject(reason)
          },
        )
      }
    })
  }
  
}

Resolve

resolve(value) {
    if (this.state === 'pending') {
      this.state = 'fulfilled'
      this.value = value

      this.onFulfilledCallback.forEach((fn) => {
        fn(this.value)
      })
    }
  }

Reject

reject(reason) {
    if (this.state === 'pending') {
      this.state = 'rejected'
      this.reason = reason

      this.onRejectedCallback.forEach((fn) => {
        fn(this.reason)
      })
    }
  }

Then

then(onFulfilled, onRejected) {
    if (typeof onFulfilled !== 'function') {
      onFulfilled = function (value) {
        return value
      }
    }
    if (typeof onRejected !== 'function') {
      onRejected = function (reason) {
        return reason
      }
    }

    const promise = new Promise((resolve, reject) => {
      if (this.state === 'fulfilled') {
        try {
          const result = onFulfilled(this.value)
          check(promise, result, resolve, reject)
        } catch (e) {
          reject(e)
        }
      }
      if (this.state === 'rejected') {
        try {
          const result = onRejected(this.reason)
          check(promise, result, resolve, reject)
        } catch (e) {
          reject(e)
        }
      }
      if (this.state === 'pending') {
        this.onFulfilledCallback.push((value) => {
          try {
            const result = onFulfilled(value)
            check(promise, result, resolve, reject)
          } catch (e) {
            reject(e)
          }
        })
        this.onRejectedCallback.push((reason) => {
          try {
            const result = onRejected(reason)
            check(promise, result, resolve, reject)
          } catch (e) {
            reject(e)
          }
        })
      }
    })
    return promise
  }
   function check(promise1, promise2, resolve, reject) {
    if (promise1 === promise2) {
      reject('Chaining cycle detected for Promise')
    } else {
      if (promise2 instanceof Promise) {
        promise2.then(resolve, reject)
      } else {
        resolve(promise2)
      }
    }
  }
}