wsjls-zw:1、Promise

有then方法的对象和函数:promise、thenable

两个值:value reason

异常:exception

promise三种状态和关系

1 pending

初始状态,可以改变

一个promise在resolve和reject之间,处于这个状态

resolve 到 fulfilled

reject 到 rejected

2 fulfilled

最终状态不可改变

resolve之后变成这样的状态

必须有一个value值

3 rejected

最终状态不可改变

reject之后变成这样的状态

必须有一个reason的值

#### then

promise有一个then方法用来访问最终的结果

promise.then(onFulfilled,onrejected)

1、onFulfilled,onrejected 必须是函数类型,否则被忽略

2、onFulfilled 在promise 变成 fulfilled 时,应该调用onFulfilled,参数是value

变成之前,不调用

只能被调用一次,可以设置一个变量控制次数

3、onrejected 在变成 rejected 时,调用 onrejected,参数是reason

4、onFulfilled,onrejected 应该是微任务 queueMicrotask 实现微任务

5、promise状态变成 fulfilled 之后,onfulfilled回调都需要按照then的顺序执行 用数组list执行

promise状态变成 rejected 之后,onrejected回调都需要按照then的顺序执行 用数组list执行

6、then的返回值,返回一个promise

onfulfilled和onrejected执行结果为x,调用resolvePromise方法

如果onfulfilled/onrejected执行抛出异常e,promise2要被reject

如果onfulfilled不是一个函数,promise2以promise1的value触发fulfilled

如果onrejected不是一个函数,promise2以promise1的reason触发rejected

7 resolvePromise(promise2, x, resolve, reject)

如果promise2和x相等,那么reject typeError

如果x是一个promise

如果x是Pending,promise一定继续pending,直到x变成fulfilled 或者 rejected

如果x是fulfilled,resolve same value

如果x是rejected,reject same value

如果x是Object或者function

  try

  let then=x.then;

  catch(e)

  reject promise

如果x.then是一个函数,then.call(x,resolvePromiseFn,rejectPromiseFn) 改变this指向

如果then不是一个函数,fulfilled promise x

const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";

class PromiseM {
  FULFILLED_CALLBACK_LIST = [];
  REJECTED_CALLBACK_LIST = [];
  _status = PENDING;
  constructor(fn) {
    this.status = PENDING;
    this.value = null;
    this.reason = null;
    try {
      fn(this.resolve.bind(this), this.reject.bind(this));
    } catch (e) {
      this.reject(e)
    }
  }
  get status() {
    return this._status
  }

  set status(newStatus) {
    this._status = newStatus;
    switch (newStatus) {
      case FULFILLED: {
        this.FULFILLED_CALLBACK_LIST.forEach(callback => {
          callback(this.value)
        })
        break;
      }
      case REJECTED: {
        this.REJECTED_CALLBACK_LIST.forEach(callback => {
          callback(this.reason)
        })
        break;
      }
    }
  }

  resolve(value) {
    if (this.status === PENDING) {
      this.value = value
      this.status = FULFILLED;
    }
  }

  reject(reason) {
    if (this.status === PENDING) {
      this.reason = reason
      this.status = REJECTED;
    }
  }

  then(onFulfilled, onRejected) {
    const realOnFulfilled = this.isFunction(onFulfilled) ? onFulfilled : (value) => {
      return value
    };
    const realOnRejected = this.isFunction(onRejected) ? onRejected : (reason) => {
      throw reason;
    };
    const promise2 = new PromiseM((resolve, reject) => {
      const fulfilledMicrotask = () => {
        queueMicrotask(() => {
          try {
            const x = realOnFulfilled(this.value);
            this.resolvePromise(promise2, x, resolve, reject)
          } catch (e) {
            reject(e)
          }
        })
      }
      const rejectedMicrotast = () => {
        queueMicrotask(() => {
          try {
            const x = realOnRejected(this.reason)
            this.resolvePromise(promise2, x, resolve, reject)
          } catch (e) {
            reject(e)
          }
        })
      }
      switch (this.status) {
        case FULFILLED: {
          fulfilledMicrotask();
          break;
        }
        case REJECTED: {
          rejectedMicrotast()
          break;
        }
        case PENDING: {
          this.FULFILLED_CALLBACK_LIST.push(fulfilledMicrotask)
          this.REJECTED_CALLBACK_LIST.push(rejectedMicrotast)
        }
      }
    })
    return promise2;
  }

  catch(onRejected) {
    return this.then(null, onRejected)
  }

  isFunction(param) {
    return typeof param === 'function';
  }

  resolvePromise(promise2, x, resolve, reject) {
    if (promise2 === x) {
      return reject(new TypeError('The promise and the return value are the same'))
    }
    if (x instanceof PromiseM) {
      queueMicrotask(() => {
        x.then((y) => {
          this.resolvePromise(promise2, y, resolve, reject)
        }, reject);
      })
    } else if (typeof x === 'object' || this.isFunction(x)) {
      if (x === null) {
        return resolve(x);
      }
      let then = null;
      try {
        then = x.then
      } catch (e) {
        return reject(e)
      }
      if (this.isFunction(then)) {
        let called = false;
        try {
          then.call(x,
            (y) => {
              if (called) return;
              called = true;
              this.resolvePromise(promise2, y, resolve, reject)
            },
            (r) => {
              if (called) return;
              called = true;
              reject(r)
            })
        } catch (e) {
          if (called) return;
          reject(e)
        }
      } else {
        resolve(x)
      }
    } else {
      resolve(x);
    }
  }

  static resolve(value) {
    if (value instanceof PromiseM) {
      return value
    }
    return new PromiseM((resolve) => {
      resolve(value)
    })
  }

  static reject(reason) {
    return new PromiseM((resolve, reject) => {
      reject(reason)
    })
  }

  static race(promiseList) {
    return new PromiseM((resolve, reject) => {
      const length = promiseList;
      if (length === 0) {
        return resolve()
      } else {
        for (let i = 0; i < length; i++) {
          PromiseM.resolve(promiseList[i]).then(
            (value) => {
              return resolve(value)
            },
            (reason) => {
              return reject(reason)
            }
          )
        }
      }
    })
  }

  static resolved(value) {
    var d = new Deferred();
    d.resolve(value);
    return d.promise;
  }

  static rejected(value) {
    var d = new Deferred();
    d.reject(value);
    return d.promise;
  }

}

function Deferred() {
  this.promise = new PromiseM(function (resolve, reject) {
    this._resolve = resolve;
    this._reject = reject;
  }.bind(this));
}
Deferred.prototype.resolve = function (value) {
  this._resolve.call(this.promise, value)
}
Deferred.prototype.reject = function (reason) {
  this._reject.call(this.promise, reason)
}

var dummy = {
  dummy: "dummy"
}

var sentinel = {
  sentinel: "sentinel"
}
var other = {
  other: "other"
}

function xFactory() {
  var d = new Deferred();
  setTimeout(function () {
    d.resolve(sentinel);
  }, 50);
  return {
    then: function (resolvePromise, rejectPromise) {
      resolvePromise(d.promise);
      rejectPromise(other);
    }
  }
}

var promise = PromiseM.resolved(dummy).then(function onBasePromiseFulfilled() {
  return xFactory();
})

promise.then(res => {
  console.log("success", res)
}, res => {
  console.log("err", res)
})

const test = new PromiseM((resolve, reject) => {
  setTimeout(() => {
    reject(111)
  }, 1000);
}).then((value) => {
  console.log('then', value)
}).catch((reason) => {
  console.log('catch')
})

function longTimeFn(time) {
  return new Promise((resolve) => {
    setTimeout(() => {
      resolve(time);
    }, time);
  })
}
function* generator() {
  const list = [1, 2, 3]
  for (let i of list) {
    yield i
  }
}
let g = generator();
// console.log(g.next())
// console.log(g.next())
// console.log(g.next())
// console.log(g.next())

function asyncFunc(generator) {
  const iterator = generator();
  const next = data => {
    const { value, done } = iterator.next(data);
    if (done) { return };
    value.then(data => {
      next(data);
    })
  }
  next();
}
asyncFunc(function* () {
  let data = yield longTimeFn(1000);
  console.log(data);
  data = yield longTimeFn(2000);
  console.log(data);
  return data
})

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值