手写promis(2)-- 链式编程篇

目录

链式编程 处理异常 和普通内容

链式编程---处理返回promise

链式编程---处理重复引用

链式编程--rejected 

链式编程--处理padding状态


链式编程 处理异常 和普通内容

  • 1.返回promise实例:在原本then方法里边创建新promise
  • 2.获取返回值:把原本的then的逻辑迁移到新promise中 是同步执行的不受影响(方便传递给新创建的promise)
  • 3.处理返回值 调用新promise的 resolve 
  • 4.处理异常 try catch 捕获异常 调用新promise的 reject

function runAsyncTask(callback) {
  if (typeof queueMicrotask === "function") {
    queueMicrotask(callback);
  } else if (typeof MutationObserver == "function") {
    const obs = new MutationObserver(callback);
    const divNode = document.createElement("div");
    obs.observe(divNode, { childList: true });
    divNode.innerHTML = "贾公子";
  } else {
    setTimeout(callback, 0);
  }
}

/**链式编程 处理异常 和普通内容
 *   1.返回promise实例
 *   2.获取返回值
 *    2.1处理返回值
 *    2.2处理异常
 *
 *
 */
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";

class MyPromise {
  state = PENDING;
  result = undefined;
  #handlers = [];
  constructor(func) {
    const resolve = (result) => {
      if (this.state == PENDING) {
        this.state = FULFILLED;
        this.result = result;
        this.#handlers.forEach(({ onFulfilled }) => {
          onFulfilled(this.result);
        });
      }
    };

    const reject = (result) => {
      if (this.state == PENDING) {
        this.state = REJECTED;
        this.result = result;
        this.#handlers.forEach(({ onRejected }) => {
          onRejected(this.result);
        });
      }
    };

    func(resolve, reject);
  }

  then(onFulfilled, onRejected) {
    onFulfilled = typeof onFulfilled === "function" ? onFulfilled : (x) => x;

    onRejected =
      typeof onRejected === "function"
        ? onRejected
        : (x) => {
            throw x;
          };
    //  1.返回promise实例
    const p2 = new MyPromise((resolve, reject) => {
      if (this.state === FULFILLED) {
        runAsyncTask(() => {
          try {
            // 2.获取返回值
            const x = onFulfilled(this.result);
            // 2.1处理返回值
            resolve(x);
            // 2.2处理异常
          } catch (error) {
            reject(error);
          }
        });
      } else if (this.state === REJECTED) {
        runAsyncTask(() => {
          onRejected(this.result);
        });
      } else if (this.state === PENDING) {
        this.#handlers.push({
          onFulfilled: () => {
            runAsyncTask(() => {
              onFulfilled(this.result);
            });
          },
          onRejected: () => {
            runAsyncTask(() => {
              onRejected(this.result);
            });
          },
        });
      }
    });

    return p2;
  }
}

// 测试代码

const p = new MyPromise((resolve, reject) => {
  resolve("1");
  // reject("error");
});
p.then((result) => {
  console.log("p1", result);
  throw new Error("异常");
  // return 2;
}).then(
  (result) => {
    console.log("p2", result);
  },
  (err) => {
    console.log("p2", err);
  }
);

链式编程---处理返回promise

1.使用 instanceof判断返回值是否为 MyPromise实例

2.如果是代表传递的返回值是promise 调用传递的promise的then方法

3.在成功回调中调用resolve,失败回调中传递reject,把结果传递

function runAsyncTask(callback) {
  if (typeof queueMicrotask === "function") {
    queueMicrotask(callback);
  } else if (typeof MutationObserver == "function") {
    const obs = new MutationObserver(callback);
    const divNode = document.createElement("div");
    obs.observe(divNode, { childList: true });
    divNode.innerHTML = "贾公子";
  } else {
    setTimeout(callback, 0);
  }
}

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

class MyPromise {
  state = PENDING;
  result = undefined;
  #handlers = [];
  constructor(func) {
    const resolve = (result) => {
      if (this.state == PENDING) {
        this.state = FULFILLED;
        this.result = result;
        this.#handlers.forEach(({ onFulfilled }) => {
          onFulfilled(this.result);
        });
      }
    };

    const reject = (result) => {
      if (this.state == PENDING) {
        this.state = REJECTED;
        this.result = result;
        this.#handlers.forEach(({ onRejected }) => {
          onRejected(this.result);
        });
      }
    };

    func(resolve, reject);
  }

  then(onFulfilled, onRejected) {
    onFulfilled = typeof onFulfilled === "function" ? onFulfilled : (x) => x;

    onRejected =
      typeof onRejected === "function"
        ? onRejected
        : (x) => {
            throw x;
          };
    const p2 = new MyPromise((resolve, reject) => {
      if (this.state === FULFILLED) {
        runAsyncTask(() => {
          try {
            const x = onFulfilled(this.result);
            // 1.处理返回promise
            if (x instanceof MyPromise) {
              // 2.调用then方法
              x.then(
                (res) => {
                  resolve(res);
                },
                (err) => {
                  reject(err);
                }
              );
            } else {
              resolve(x);
            }
          } catch (error) {
            reject(error);
          }
        });
      } else if (this.state === REJECTED) {
        runAsyncTask(() => {
          onRejected(this.result);
        });
      } else if (this.state === PENDING) {
        this.#handlers.push({
          onFulfilled: () => {
            runAsyncTask(() => {
              onFulfilled(this.result);
            });
          },
          onRejected: () => {
            runAsyncTask(() => {
              onRejected(this.result);
            });
          },
        });
      }
    });

    return p2;
  }
}

// 测试代码

const p = new MyPromise((resolve, reject) => {
  resolve("1");
});
p.then((result) => {
  return new MyPromise((resolve, reject) => {
    resolve(2);
    // reject("err");
  });
}).then(
  (result) => {
    console.log("p2", result);
  },
  (err) => {
    console.log("p2", err);
  }
);

链式编程---处理重复引用

在then的回调函数中直接把then的结果返回了会抛出重复引用的问题

1.x就是then回调函数的返回值,then方法返回的promise就是p2

2.比较x跟p2是否全等 是就抛出异常 

function runAsyncTask(callback) {
  if (typeof queueMicrotask === "function") {
    queueMicrotask(callback);
  } else if (typeof MutationObserver == "function") {
    const obs = new MutationObserver(callback);
    const divNode = document.createElement("div");
    obs.observe(divNode, { childList: true });
    divNode.innerHTML = "贾公子";
  } else {
    setTimeout(callback, 0);
  }
}

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

class MyPromise {
  state = PENDING;
  result = undefined;
  #handlers = [];
  constructor(func) {
    const resolve = (result) => {
      if (this.state == PENDING) {
        this.state = FULFILLED;
        this.result = result;
        this.#handlers.forEach(({ onFulfilled }) => {
          onFulfilled(this.result);
        });
      }
    };

    const reject = (result) => {
      if (this.state == PENDING) {
        this.state = REJECTED;
        this.result = result;
        this.#handlers.forEach(({ onRejected }) => {
          onRejected(this.result);
        });
      }
    };

    func(resolve, reject);
  }

  then(onFulfilled, onRejected) {
    onFulfilled = typeof onFulfilled === "function" ? onFulfilled : (x) => x;

    onRejected =
      typeof onRejected === "function"
        ? onRejected
        : (x) => {
            throw x;
          };
    const p2 = new MyPromise((resolve, reject) => {
      if (this.state === FULFILLED) {
        runAsyncTask(() => {
          try {
            const x = onFulfilled(this.result);
            // 1.处理重复的引用
            if (x === p2) {
              console.log("----");
              throw new TypeError(
                "Chaining cycle detected for promise #<Promise>"
              );
            }
            if (x instanceof MyPromise) {
              x.then(
                (res) => {
                  resolve(res);
                },
                (err) => {
                  reject(err);
                }
              );
            } else {
              resolve(x);
            }
          } catch (error) {
            reject(error);
          }
        });
      } else if (this.state === REJECTED) {
        runAsyncTask(() => {
          onRejected(this.result);
        });
      } else if (this.state === PENDING) {
        this.#handlers.push({
          onFulfilled: () => {
            runAsyncTask(() => {
              onFulfilled(this.result);
            });
          },
          onRejected: () => {
            runAsyncTask(() => {
              onRejected(this.result);
            });
          },
        });
      }
    });

    return p2;
  }
}

// 测试代码

const p = new MyPromise((resolve, reject) => {
  resolve("1");
});
const p2 = p.then((res) => {
  return p2;
});
p2.then(
  (res) => {},
  (err) => {
    console.log(err);
  }
);

链式编程--rejected 

完成链式第一步要返回promise 处理Fulfilled时候已完成

通过trycatch 处理异常

抽离函数 resolvePromise 处理 重复引用 以及返回promise的情况

调用函数测试状态

function runAsyncTask(callback) {
  if (typeof queueMicrotask === "function") {
    queueMicrotask(callback);
  } else if (typeof MutationObserver == "function") {
    const obs = new MutationObserver(callback);
    const divNode = document.createElement("div");
    obs.observe(divNode, { childList: true });
    divNode.innerHTML = "贾公子";
  } else {
    setTimeout(callback, 0);
  }
}

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

class MyPromise {
  state = PENDING;
  result = undefined;
  #handlers = [];
  constructor(func) {
    const resolve = (result) => {
      if (this.state == PENDING) {
        this.state = FULFILLED;
        this.result = result;
        this.#handlers.forEach(({ onFulfilled }) => {
          onFulfilled(this.result);
        });
      }
    };

    const reject = (result) => {
      if (this.state == PENDING) {
        this.state = REJECTED;
        this.result = result;
        this.#handlers.forEach(({ onRejected }) => {
          onRejected(this.result);
        });
      }
    };

    func(resolve, reject);
  }

  /**
   *处理异常
   */
  then(onFulfilled, onRejected) {
    onFulfilled = typeof onFulfilled === "function" ? onFulfilled : (x) => x;

    onRejected =
      typeof onRejected === "function"
        ? onRejected
        : (x) => {
            throw x;
          };
    const p2 = new MyPromise((resolve, reject) => {
      if (this.state === FULFILLED) {
        runAsyncTask(() => {
          try {
            const x = onFulfilled(this.result);
            resolvePromise(p2, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        });
      } else if (this.state === REJECTED) {
        // 1.处理异常
        runAsyncTask(() => {
          try {
            // 2.获取返回值
            const x = onRejected(this.result);
            // 4.调用函数
            resolvePromise(p2, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        });
      } else if (this.state === PENDING) {
        this.#handlers.push({
          onFulfilled: () => {
            runAsyncTask(() => {
              onFulfilled(this.result);
            });
          },
          onRejected: () => {
            runAsyncTask(() => {
              onRejected(this.result);
            });
          },
        });
      }
    });

    return p2;
  }
}
// 3.抽取函数
function resolvePromise(p2, x, resolve, reject) {
  if (x === p2) {
    throw new TypeError("Chaining cycle detected for promise #<Promise>");
  }
  if (x instanceof MyPromise) {
    x.then(
      (res) => {
        resolve(res);
      },
      (err) => {
        reject(err);
      }
    );
  } else {
    resolve(x);
  }
}

// 测试代码

const p = new MyPromise((resolve, reject) => {
  reject("1");
});
const p2 = p.then(undefined, (err) => {
  // throw "error";
  // return p2;
  // return 2;
  return new MyPromise((resolve, reject) => {
    resolve("OK");
    reject("ERROR");
  });
});
p2.then(
  (res) => {
    console.log("p2--res", res);
  },
  (err) => {
    console.log("p2--err", err);
  }
);

链式编程--处理padding状态

PENDING状态要根据异步执行的结果存储到handlers数组中不同的函数(onFulfilled || onRejected)两个处理链式编程的逻辑完全一样

   * 处理异常 trycatch捕获异常

   * 获取返回值 获取第一个promise的返回值

   * 调用函数 处理 重复引用以及 返回promise的情况

function runAsyncTask(callback) {
  if (typeof queueMicrotask === "function") {
    queueMicrotask(callback);
  } else if (typeof MutationObserver == "function") {
    const obs = new MutationObserver(callback);
    const divNode = document.createElement("div");
    obs.observe(divNode, { childList: true });
    divNode.innerHTML = "贾公子";
  } else {
    setTimeout(callback, 0);
  }
}

function resolvePromise(p2, x, resolve, reject) {
  if (x === p2) {
    throw new TypeError("Chaining cycle detected for promise #<Promise>");
  }
  if (x instanceof MyPromise) {
    x.then(
      (res) => {
        resolve(res);
      },
      (err) => {
        reject(err);
      }
    );
  } else {
    resolve(x);
  }
}
const PENDING = "pending";
const FULFILLED = "fulfilled";
const REJECTED = "rejected";

class MyPromise {
  state = PENDING;
  result = undefined;
  #handlers = [];
  constructor(func) {
    const resolve = (result) => {
      if (this.state == PENDING) {
        this.state = FULFILLED;
        this.result = result;
        this.#handlers.forEach(({ onFulfilled }) => {
          onFulfilled(this.result);
        });
      }
    };

    const reject = (result) => {
      if (this.state == PENDING) {
        this.state = REJECTED;
        this.result = result;
        this.#handlers.forEach(({ onRejected }) => {
          onRejected(this.result);
        });
      }
    };

    func(resolve, reject);
  }
  /**
   * 处理异常
   * 获取返回值
   * 调用函数
   */
  then(onFulfilled, onRejected) {
    onFulfilled = typeof onFulfilled === "function" ? onFulfilled : (x) => x;

    onRejected =
      typeof onRejected === "function"
        ? onRejected
        : (x) => {
            throw x;
          };
    const p2 = new MyPromise((resolve, reject) => {
      if (this.state === FULFILLED) {
        runAsyncTask(() => {
          try {
            const x = onFulfilled(this.result);
            resolvePromise(p2, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        });
      } else if (this.state === REJECTED) {
        runAsyncTask(() => {
          try {
            const x = onRejected(this.result);

            resolvePromise(p2, x, resolve, reject);
          } catch (error) {
            reject(error);
          }
        });
      } else if (this.state === PENDING) {
        this.#handlers.push({
          onFulfilled: () => {
            runAsyncTask(() => {
              // 处理异常
              try {
                // 获取返回值
                const x = onFulfilled(this.result);
                //  调用函数
                resolvePromise(p2, x, resolve, reject);
              } catch (error) {
                reject(error);
              }
            });
          },
          onRejected: () => {
            runAsyncTask(() => {
              // 处理异常
              try {
                // 获取返回值
                const x = onRejected(this.result);
                //  调用函数
                resolvePromise(p2, x, resolve, reject);
              } catch (error) {
                reject(error);
              }
            });
          },
        });
      }
    });

    return p2;
  }
}

// 测试代码

const p = new MyPromise((resolve, reject) => {
  setTimeout(() => {
    resolve("1");
  }, 2000);
});
const p2 = p.then((res) => {
  // throw "error";
  // return p2;
  // return 2;
  return new MyPromise((resolve, reject) => {
    setTimeout(() => {
      resolve("OK");
    }, 2000);
    // reject("ERROR");
  });
});
p2.then(
  (res) => {
    console.log("p2--res", res);
  },
  (err) => {
    console.log("p2--err", err);
  }
);

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/175509.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

淘宝商品详情页面数据(商品详情数据,商品sku数据,商品价格数据,商品优惠券数据,商品评论数据)接口代码流

淘宝API接口可以运用到多种业务场景中&#xff0c;以下列举了一些主要的场景&#xff1a; 商品信息展示&#xff1a;通过调用淘宝API详情接口&#xff0c;可以获取商品的详细信息&#xff0c;如商品标题、价格、库存、销量、评价等数据。这些信息可以用于在自己的网站或应用程…

WIN10 WIN11 12代 13代 大小核;性能核;电源选项;P-core,E-core;

WIN10 WIN11 12代 13代 大小核&#xff1b;性能核&#xff1b;电源选项&#xff1b;P-core,E-core&#xff1b; WIN10 WIN11 12代 13代 大小核;性能核&#xff1b;电源选项&#xff1b;P-core,E-core;说明&#xff1a;方法&#xff1a;1。右键开始菜单&#xff0c;选择“Window…

arcgis中投影文件(.prj)和地理转换文件(.gtf)存储路径

1、投影文件&#xff08;自定义的.prj&#xff09;的存储路径 C:\Users\14635\AppData\Roaming\ESRI\Desktop10.5\ArcMap\Coordinate Systems 2、地理转换文件&#xff08;.gtf&#xff09;--自定义 C:\Users\14635\AppData\Roaming\ESRI\Desktop10.5\ArcToolbox\CustomTransfo…

早安,朋友!每天问候语祝你天天好心情,事事都顺意

1、今天的风儿轻柔无比&#xff0c;今天的花儿香飘万里&#xff1b;今天的鸟儿十分欢喜&#xff0c;今天的云儿满载笑意&#xff1b;今天的事儿万分顺利&#xff0c;今天的人儿如此甜蜜&#xff0c;所有美好的一切同我的早安连在一起&#xff0c;祝你天天好心情&#xff0c;事事…

护眼灯什么价位的好?适合学生入手的护眼台灯推荐

据60年前的统计&#xff0c;中国人口的近视率约为10%至20%。 国家卫健委发布的中国首份眼健康白皮书显示&#xff0c;我国小学生近视率为47.2%&#xff0c;初中生近视率为75.8%&#xff0c;大学生近视率超过90%。如今&#xff0c;“低头族”随处可见&#xff0c;近视人群日益增…

污水处理智能化:污水处理拓扑图的未来发展趋势

随着城市化进程的不断加速&#xff0c;城市污水处理已经成为了一个重要的问题。污水处理不仅关系到城市环境的质量&#xff0c;还直接影响着人们的生活质量和健康。污水处理拓扑图作为一种新型的污水处理技术&#xff0c;已经被广泛应用于各种污水处理设施中。本文将介绍污水处…

【shell】shell指令学习

仅供本人自学&#xff0c;完全从自己可以理解的角度写的&#xff0c;知识点都是copy网上已有的学习资料&#xff0c;侵权请联系本人删除&#xff0c;谢谢。 1. 文本资料学习 学习Linux&#xff0c;从掌握grep、sed、awk开始吧。 Linux文本三剑客超详细教程—grep、sed、awk …

排序算法--选择排序

实现逻辑 ① 第一轮从下标为 1 到下标为 n-1 的元素中选取最小值&#xff0c;若小于第一个数&#xff0c;则交换 ② 第二轮从下标为 2 到下标为 n-1 的元素中选取最小值&#xff0c;若小于第二个数&#xff0c;则交换 ③ 依次类推下去…… void print_array(int a[], int n){f…

NX二次开发UF_CAM_PREF_ask_logical_value 函数介绍

文章作者&#xff1a;里海 来源网站&#xff1a;https://blog.csdn.net/WangPaiFeiXingYuan UF_CAM_PREF_ask_logical_value Defined in: uf_cam_prefs.h int UF_CAM_PREF_ask_logical_value(UF_CAM_PREF_t pref, logical * value ) overview 概述 This function provides …

线性代数 - 几何原理

目录 序言向量的定义线性组合、张成空间与向量基线性变换和矩阵线性复合变换与矩阵乘法三维空间的线性变换行列式矩阵的秩和逆矩阵维度变换点乘叉乘基变换特征值和特征向量抽象向量空间 序言 欢迎阅读这篇关于线性代数的文章。在这里&#xff0c;我们将从一个全新的角度去探索线…

python算法例16 数字判断

1. 问题描述 给定一个字符串&#xff0c;验证其是否为数字。 2. 问题示例 &#xff02;0&#xff02;判断为True&#xff0c;&#xff02;0.1&#xff02;判断为True&#xff0c;&#xff02;abc&#xff02;判断为False&#xff0c;&#xff02;1 a&#xff02;判断为False…

获取Greenplum 的元数据信息,schema下面的表和列信息

查询指定schema下面的表 select | || t.tablename as tab_name, coalesce(replace(obj_description((t.SCHEMANAME||."||t.TABLENAME||") ::regclass), |, ),) || | AS tab_desc from pg_tables t where t.schemaname dcf_user and not exists (select x f…

2304. 网格中的最小路径代价 : 从「图论最短路」过渡到「O(1) 空间的原地模拟」

题目描述 这是 LeetCode 上的 「2304. 网格中的最小路径代价」 &#xff0c;难度为 「中等」。 Tag : 「最短路」、「图」、「模拟」、「序列 DP」、「动态规划」 给你一个下标从 0 开始的整数矩阵 grid&#xff0c;矩阵大小为 m x n&#xff0c;由从 0 到 的不同整数组成。 你…

【每日一题】2304. 网格中的最小路径代价-2023.11.22

题目&#xff1a; 2304. 网格中的最小路径代价 给你一个下标从 0 开始的整数矩阵 grid &#xff0c;矩阵大小为 m x n &#xff0c;由从 0 到 m * n - 1 的不同整数组成。你可以在此矩阵中&#xff0c;从一个单元格移动到 下一行 的任何其他单元格。如果你位于单元格 (x, y) …

集成电路工厂用什么ERP?哪家的集成电路ERP比较好

集成电路通常对制造工艺、生产设备、品质检验等方面有较高的要求&#xff0c;而随着智能技术和自动化技术的发展成熟&#xff0c;如今集成电路行业逐渐迈入数字化和智能化阶段&#xff0c;而至这个时代背景当中&#xff0c;很多集成电路工厂借助ERP实现信息化转型升级。 时至今…

(论文阅读58-66)视频描述

58.文献阅读笔记&#xff08;LRCNs&#xff09; 简介 题目 Long-term Recurrent Convolutional Networks for Visual Recognition and Description 作者 Jeff Donahue, Lisa Anne Hendricks, Marcus Rohrbach, Subhashini Venugopalan, Sergio Guadarrama, Kate Saenko, T…

台灯应该买什么样的才能护眼?权威榜五大上榜护眼台灯品牌推荐

《中华眼视光学与视觉科学杂志》上的一篇文章称&#xff0c;近视是世界范围内的高发疾病&#xff0c;当前全球近视患病率超过28.3%&#xff0c;预计到2050年将达到49.8%。 据国家卫生健康委员会数据显示&#xff0c;我国超7亿人为近视患者&#xff0c;其中&#xff0c;儿童青少…

特征工程完整指南 - 第一部分

苏米特班迪帕迪亚 一、说明 特征工程是利用领域知识从原始数据中提取特征的过程。这些功能可用于提高机器学习算法的性能。本篇叙述在特征选择过程的若干数据处理。 一般来说&#xff0c;特征工程有以下子步骤&#xff1a; 特征转换特征构建特征选择特征提取 二、特征转换的缺…

全志R128芯片RTOS调试指南

RTOS 调试指南 此文档介绍 FreeRTOS 系统方案支持的常用软件调试方法&#xff0c;帮助相关开发人员快速高效地进行软件调试&#xff0c;提高解决软件问题的效率。 栈回溯 栈回溯是指获取程序的调用链信息&#xff0c;通过栈回溯信息&#xff0c;能帮助开发者快速理清程序执行…