JavaScript手写函数-第三篇

148 阅读1分钟

Promise

  • 模拟一个简单的 Promise 方法
class MyPromise {
  constructor(fn) {
    this.status = 'pending';
    this.successArr = [];
    this.errorFn = [];

    const resolve = (res) => {
      if (this.status === 'pending') {
        this.status = 'fulfilled';
        this.successArr.forEach(f = f(res));
      }
    }
    const reject = (err) => {
      if (this.status === 'pending') {
        this.status = 'rejected';
        this.errorFn.forEach(f = f(err));
      }
    }
    // 定义函数
    try {
      fn(resolve, reject);
    } catch (err) {
      reject(err)
    }
  }
  then(successFn, failFn) {
    // 同步
    if ('success' === this.status) {
      onSuccess(this.result)
    }
    if ('fail' === this.status) {
      onFail(this.reason)
    }

    // 异步
    if (this.status === 'pending') {
      this.successArr.push(successFn);
      this.errorFn.push(failFn);
    }
  }
}

new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve(1);
  }, 2000)
}).then((res) => {
  console.log('success:', res);
}, err => {
  console.log('fail', err);
})

new Promise((resolve, reject) => {
  setTimeout(() => {
    reject(2);
  }, 2000)
}).then((res) => {
  console.log('success:', res);
}, err => {
  console.log('fail', err);
})

PromiseRace

  • 模拟一个简单的 Promise.race 方法
function PromiseRace(promiseArr) {
  return new Promise((resolve, reject) => {
    if (!Array.isArray(promiseArr)) return reject(new TypeError('is not Array'));
    promiseArr.forEach(item => {
      Promise.resolve(item()).then(res => resolve(res), err => reject(err))
    })
  })
}
function a() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('PromiseRace a');
    }, 2000)
  })
}
function b() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('PromiseRace b');
    }, 1000)
  })
}
PromiseRace([a, b]).then(arr => {
  console.log(arr);
}, err => {
  console.log(err)
})

PromiseAll

  • 模拟一个简单的 Promise.all 方法
function PromiseAll(promiseArr) {
  const vResult = new Array(promiseArr.length);
  return new Promise((resolve, reject) => {
    if (!Array.isArray(promiseArr)) return reject(new TypeError('is not Array'));
    let vLen = 0;
    for (let i = 0; i < promiseArr.length; i += 1) {
      Promise.resolve(promiseArr[i]()).then(res => {
        vResult[i] = res;
        vLen++;
        if (vLen === promiseArr.length) resolve(vResult);
      }, err => {
        reject(err);
      })
    }
  })
}
function a() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('hello a');
    }, 2000)
  })
}
function b() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('hello b');
    }, 1000)
  })
}
PromiseAll([a, b]).then(arr => {
  console.log(arr);
}, err => {
  console.log(err)
})