ts: 实现promise

ts实现的promise和js实现的promise有什么使用上的区别

  1. 类型注解
    可以为 Promise 指定明确的返回类型,如 Promise< string>、Promise<number[]> 等。这有助于在编译时捕获类型错误
  2. 类型推断
    ts的类型推断功能可以自动推断出 Promise 的返回类型, 提高了代码的可读性。
  3. 类型安全性
    如果你尝试将一个 Promise 的解析值赋给一个不兼容的类型,TypeScript 编译器会报错。
  4. 更好的文档和代码提示
    再ide中会提供更好的文档和代码提示,包括 Promise 的类型信息、参数列表、返回值等,有助于你更快地理解代码并减少错误

示例1

// 示例: myPromise.resolve类型推断
let aa1 = myPromise.resolve("123");
let aa2 = Promise.resolve("123");

示例2

// 示例: Promise<string> 是一个类型注解
// 定义一个返回Promise<string>的函数
// let myPromise: Promise<string>;
// myPromise = new Promise((resolve, reject) => {
//   // ... 异步操作
//   resolve('这是另一个返回的字符串数据');
// });
function fetchMessageFromServer(): myPromise<string> {
  // 假设这是一个模拟的异步操作,例如从服务器获取数据
  return new myPromise<string>((resolve, reject) => {
    setTimeout(() => {
      // 模拟成功获取数据
      const message = 123;
      resolve(message); // 解析并返回字符串
    }, 2000); // 假设这个操作需要2秒钟
  });
}

// 使用fetchMessageFromServer函数并处理其结果
fetchMessageFromServer()
  .then((message) => {
    console.log(message); // 输出:Hello from the server!
    console.log(message.length); // 输出:21
  })
  .catch((error) => {
    console.error("An error occurred:", error);
  });

// 注意:在TypeScript中,通常不需要显式指定.then和.catch的参数类型,因为它们可以从Promise的泛型参数中推断出来。

// 如果你使用async/await语法,代码会更加简洁和直观:
async function printMessageFromServer() {
  try {
    const message = await fetchMessageFromServer();
    console.log(message); // 输出:Hello from the server!
    console.log(message.length); // 输出:21
  } catch (error) {
    console.error("An error occurred:", error);
  }
}

printMessageFromServer();

ts实现promise代码

// 2.1 promise有三个状态
const PENDING = "pending"; // 等待
const FULLFILLED = "fullfilled"; // 成功
const REJECTED = "rejected"; // 失败

// 1. promise是一个类, 执行类需要传递构造函数并立即执行
class myPromise<T> {
  constructor(executor) {
    // 构造函数constructor是一个类必须要有的方法,默认返回实例对象
    try {
      executor(this.resolve, this.reject);
    } catch (e) {
      this.reject(e);
    }
  }
  status = PENDING; // 状态
  value: T; // 成功的值默认是没有的是undefined
  reason: any; // 失败的值默认是没有的是undefined
  successCallback: Array<((value: T) => any) | null> = [];
  fallCallback: Array<((reason: any) => any) | null> = [];
  resolve = (value: T) => {
    // 2.2 如果状态不是等待,阻止程序向下执行(因为Promise有三个状态,只能 pending -> fullfilled / pending -> rejected, 一旦状态确定就不可改变)
    if (this.status !== PENDING) return;
    this.status = FULLFILLED; // 更改状态为成功
    this.value = value; // 保存成功的值
    // 5.2 判断成功回调函数是否存在,存在调用
    // this.successCallback && this.successCallback(this.value)
    // while (this.successCallback.length) this.successCallback.shift()(this.value)
    while (this.successCallback.length) {
      const callback = this.successCallback.shift();
      if (callback) callback(this.value);
    }
    // this.successCallback.shift()();
  }; // 箭头函数让函数内部指向类
  reject = (reason) => {
    // 2.3 如果状态不是等待,阻止程序向下执行(因为Promise有三个状态,只能 pending -> fullfilled / pending -> rejected, 一旦状态确定就不可改变)
    if (this.status !== PENDING) return;
    this.status = REJECTED; // 更改状态为失败
    this.reason = reason; // 保存失败的原因
    // 5.2 判断失败回调函数是否存在,存在调用
    // this.fallCallback && this.fallCallback(this.reason)
    // while (this.fallCallback.length) this.fallCallback.shift()(this.reason)
    // while (this.fallCallback.length) this.fallCallback.shift()();
    while (this.fallCallback.length) {
      const callback = this.fallCallback.shift();
      if (callback) callback(this.reason);
    }
  };
  then(
    successCallback?: (value: T) => any,
    fallCallback?: (reason: any) => any
  ) {
    // ???这两行代码意义何在
    successCallback = successCallback ? successCallback : (value) => value;
    fallCallback = fallCallback
      ? fallCallback
      : (reason) => {
          throw reason;
        };

    // 11. 传递
    console.log("this.status", this.status);
    // 返回promise对象可进行链式调用,并在把上一个then传给下一个then
    let promise2 = new myPromise((resolve, reject) => {
      // 3. then方法内部就是判断状态的,状态是成功调用成功回调,失败调用失败回调
      if (this.status === FULLFILLED) {
        // 9.2 同步代码执行后就可以拿到promise
        // setTimeout(() => {
        try {
          // 4.1 then成功的回调有一个参数,表示成功的值(默认是空的,就是undefined)
          let x = successCallback(this.value);
          // 判断x的值是普通值还是promise对象
          // 如果是普通值直接resolve
          // 如果是promise对象则查看返回的结果,根据这个结果决定调用resolve还是reject
          // resolve(x)
          resolvePromise(promise2, x, resolve, reject);
        } catch (e) {
          reject(e);
        }
        // }, 0)
      } else if (this.status === REJECTED) {
        // 4.2 then失败的回调有一个参数,表示失败的原因
        // fallCallback(this.reason)
        // let y = fallCallback(this.reason)
        // reject(y)
        // setTimeout(() => {
        try {
          // 4.1 then成功的回调有一个参数,表示成功的值(默认是空的,就是undefined)
          let x = fallCallback(this.reason);
          // 判断x的值是普通值还是promise对象
          // 如果是普通值直接resolve
          // 如果是promise对象则查看返回的结果,根据这个结果决定调用resolve还是reject
          // resolve(x)
          resolvePromise(promise2, x, resolve, reject);
        } catch (e) {
          reject(e);
        }
        // }, 0)
      } else {
        // 等待状态
        // 5.1  将成功和失败的状态存储起来
        // this.successCallback = successCallback
        // this.fallCallback = fallCallback
        // this.successCallback.push(successCallback)
        // this.fallCallback.push(fallCallback)
        this.successCallback.push(() => {
          // setTimeout(() => {
          try {
            // 4.1 then成功的回调有一个参数,表示成功的值(默认是空的,就是undefined)
            let x = successCallback(this.value);
            // 判断x的值是普通值还是promise对象
            // 如果是普通值直接resolve
            // 如果是promise对象则查看返回的结果,根据这个结果决定调用resolve还是reject
            // resolve(x)
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            reject(e);
          }
          // }, 0)
        });
        this.fallCallback.push(() => {
          // setTimeout(() => {
          try {
            // 4.1 then成功的回调有一个参数,表示成功的值(默认是空的,就是undefined)
            let x = fallCallback(this.reason);
            // 判断x的值是普通值还是promise对象
            // 如果是普通值直接resolve
            // 如果是promise对象则查看返回的结果,根据这个结果决定调用resolve还是reject
            // resolve(x)
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            reject(e);
          }
          // }, 0)
        });
      }
    });
    return promise2;
  }
  finally(callback) {
    return this.then(
      (value) => {
        // callback()
        // return value
        return myPromise.resolve(callback()).then(() => value);
      },
      (reason) => {
        // callback()
        // // throw reason ???为什么我这么不会执行到finally后面的then
        // return reason
        return myPromise.resolve(callback()).then(() => {
          throw reason;
        });
      }
    );
  }
  catch(fallCallback) {
    return this.then(undefined, fallCallback);
  }
  static all(array) {
    // 如果是promise保存结果,如果是普通值也保存下来,最后一并返回
    let result: any[] = [];
    let index = 0;
    console.log("all");
    return new myPromise((resolve, reject) => {
      function addData(key: number, value) {
        result[key] = value;
        index++;
        if (index === array.length) {
          resolve(result);
        }
      }
      for (let i: number = 0; i < array.length; i++) {
        let current = array[i];
        if (current instanceof myPromise) {
          // promise 对象
          current.then(
            (value) => addData(i, value),
            (reason) => reject(reason)
          );
        } else {
          // 普通值
          addData(i, array[i]);
        }
      }
    });
  }
  static resolve(value) {
    if (value instanceof myPromise) return value;
    return new myPromise((resolve) => resolve(value));
  }
}

function resolvePromise(promise2, x, resolve, reject) {
  if (promise2 === x) {
    // 9.1 避免then中同一个promise循环返回
    return reject(
      new TypeError("Chaining cycle detected for promise #<Promise>")
    );
  }
  if (x instanceof myPromise) {
    // x.then((value) => {resolve(value)}, reason => reject(reason))
    x.then(resolve, reject);
  } else {
    resolve(x);
  }
}

// 在node中
// module.exports = myPromise
// 在es6中
// export const myPromise = myPromise
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值