Polyfill

Promise.all

Promise.allPolyfill = function(promises){
  return new Promise((resolve, reject) =>{
                    let pending = promises.length;
    let result = new Array(pending);
    promises.forEach((promise, index)=>{
      promise.then((res) => {
        console.log(res);
        result[index] = res; // this thing i missed
        pending --;
        if(pending === 0) resolve(result);
      }).catch((error)=> {
        reject(error);
      });
    })
                     });
}

let p1 = new Promise((resolve, reject) => resolve("p1"));
let p2 = new Promise((resolve, reject) => resolve("p2"));
let p3 = new Promise((resolve, reject) => resolve("p3"));

Promise.allPolyfill([p1, p2, p3]).then((data)=> console.log(data));

Deboune

function debounce(cb, delay){
  let timeoutId;
  
  return function(...args){  // ... args i missed
    if(timeoutId)
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() =>{
      cb(...args); // calling cb inside the funciton instead of just passing cb
    }, delay);
  }
}


function callbackFun(){
  console.log('abc');
}

let db = debounce(callbackFun, 100); // i missed the way debounce is used
// Call the debounced function with varying delays
setTimeout(db, 50);   // This call will be debounced
setTimeout(db, 150);  // This call will be debounced
setTimeout(db, 350);  // Only this call will execute after 100 ms

Throttle

const myThrottle = (cb, d) =>{
    let last = 0;

    return function(...args) {
        let current = Date.now();
        if(last && (current - last < d)){
            // do nothing
        }else{
            last = current;
            cb(...args);
        }
    }
  }

Promise handling promise chaining with only supports of a single onResolveCb and onRejectCb. Native Promises support multiple .then() and .catch() calls by maintaining a list of callbacks.

function MyPromisePolyfill(executor) {
  let value, onResolveCb, onRejectCb, isCalled = false, isResolved = false, isRejected = false;

  function resolve(val) {
    value = val;
    isResolved = true;
    if (typeof onResolveCb === 'function') {
      isCalled = true;
      onResolveCb(value);
    }
  }

  function reject(val) {
    value = val;
    isRejected = true;
    if (typeof onRejectCb === 'function') {
      isCalled = true;
      onRejectCb(value);
    }
  }

  this.then = function(cb) {
    return new MyPromisePolyfill((resolve, reject) => {
      onResolveCb = (val) => {
        try {
          const result = cb(val);
          if (result instanceof MyPromisePolyfill) {
            result.then(resolve).catch(reject);
          } else {
            resolve(result);
          }
        } catch (error) {
          reject(error);
        }
      };

      if (isResolved && !isCalled) {
        isCalled = true;
        onResolveCb(value);
      }
    });
  };

  this.catch = function(cb) {
    return new MyPromisePolyfill((resolve, reject) => {
      onRejectCb = (val) => {
        try {
          const result = cb(val);
          if (result instanceof MyPromisePolyfill) {
            result.then(resolve).catch(reject);
          } else {
            resolve(result);
          }
        } catch (error) {
          reject(error);
        }
      };

      if (isRejected && !isCalled) {
        isCalled = true;
        onRejectCb(value);
      }
    });
  };

  try {
    executor(resolve, reject);
  } catch (error) {
    reject(error);
  }
}

// Usage example
const executor = (resolve, reject) => {
  setTimeout(() => {
    resolve(2);
  }, 100);
};
let ans = 0;
let promise = new MyPromisePolyfill(executor);
promise.then((res) => {
  ans += res;
  console.log(ans);
  return new MyPromisePolyfill(executor);
}).then((res) => {
  ans += res;
  console.log('inside 2nd then', ans);
}).catch((error) => {
  console.log('error ', error);
});

Leave a Comment