Skip to content

Js 的 Promise 学习笔记

Published: at 02:48 PMSuggest Changes

简单了解一下 promise

参考文章

简单实现

class Promise {
  constructor(fn) {
    this.state = 'pending';
    this.values = null;
    this.resolveList = [];
    this.rejectList = [];
    try {
      fn(resolve, reject);
    } catch (e) {
      reject(e);
    }
    function resolve(value) {
      if (this.state === PENDING) {
        this.state = RESOLVED;
        this.value = value;
        this.resolveList.map((cb) => cb(this.value));
      }
    }

    function reject(value) {
      if (this.state === PENDING) {
        this.state = REJECTED;
        this.value = value;
        this.resolveList.map((cb) => cb(this.value));
      }
    }

    this.then = (onFulfilled, onRejected) => {
      onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : (v) => v;
      onRejected =
        typeof onRejected === 'function'
          ? onRejected
          : (r) => {
              throw r;
            };
      if (this.state === PENDING) {
        this.resolveList.push(onFulfilled);
        this.rejectList.push(onRejected);
      }
      if (this.state === RESOLVED) {
        onFulfilled(this.value);
      }
      if (this.state === REJECTED) {
        onRejected(this.value);
      }
    };
  }
}

其中 resolveList 为什么是个数组,因为可能会被 then 多次,看下面代码。网上都说的不明不白,让人不明觉厉。

代码由 霜霜家黑粉 - 资深 API 调用师 🅥 提供,还有其他群友也参与了讨论

let p = new Promise((r) => {
  setTimeout(r, 1000);
});
p.then(() => console.log('r1'));
p.then(() => console.log('r2'));

实现一个符合 Promise/A+ 规范的 Promise

这个等我有时间再说,可能明天就看

判断一个对象是否是 Promise

import { Promise as BluebirdPromise } from 'bluebird';
const test = new BluebirdPromise((resolve) => resolve('success'));
console.log(test instanceof Promise); // 输出为 false
console.log(test instanceof bluebirdPromise); // 输出为 true
function isPromise(obj) {
  return (
    !!obj &&
    (typeof obj === 'object' || typeof obj === 'function') &&
    typeof obj.then === 'function'
  );
}
function isPromise(p) {
  return p && Object.prototype.toString.call(p) === '[object Promise]';
}

一位群友分享的

让我们猜一猜点第一次会怎么样,点第二次会怎么样,为什么

<a href=" " id="app">跳转</a>
<script>
  new Promise((resolve) => {
    app.addEventListener('click', resolve);
  }).then((e) => {
    e.preventDefault();
  });
</script>

一段有助于研究 Promise 的代码

new Promise((resolve, reject) => {
  resolve(0);
  setTimeout(() => {
    resolve(1);
    console.log('resolve', 1);
  }, 1000);
  setTimeout(() => {
    reject(2);
    console.log('reject', 2);
  }, 2000);
  setTimeout(() => {
    reject(3);
    console.log('reject', 3);
  }, 2000);
}).then((res) => {
  console.log(res);
  return 2;
}).catch((err) => {
  console.log(err);
  return 3;
})

后记 感谢下面群友参与讨论,可能有漏的,漏了找我补上。。

参考文章


Previous Post
Go 语言 Gorm 数据库 ORM 框架使用问题及解决方案
Next Post
Vue 中在新标签页打开页面