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

news2024/11/15 17:44:00

目录

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

链式编程---处理返回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);
  }
);

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

jQuery实现横版手风琴效果

一、实现效果 当鼠标滑过方块的时候&#xff0c;方块的状态就会发生如下图所示的变化&#xff0c;同理当鼠标滑到其他的方块也会发生同样的效果&#xff0c;不仅大小会改变同时方块的颜色也会跟着发生变化&#xff1a; 二、代码实现 <!DOCTYPE html> <html><h…

如何通过提升客户体验带来更大的增长、更好的客户留存率?

客户期望的转变 在一个日益数字化的世界里&#xff0c;有必要采取以客户为中心的思维方式。因为客户与企业互动的方式有很多是在数字空间发生的&#xff0c;客户的需求和模式已经转变。 这种情况已经酝酿了几年&#xff0c;但在2020年才打开闸门。随着疫情的爆发&#xff0c;企…

java ssh 二手车交易管理系统eclipse开发mysql数据库MVC模式java编程网页设计

一、源码特点 JSP ssh 二手车交易管理系统是一套完善的web设计系统&#xff08;系统采用ssh框架进行设计开发&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用 B/S模式开发。开发环境为TOMCAT…

柯桥考级日语学校,日语听力如何拿满分

今天&#xff0c;来分析一下能力考听力中的五道听力题的题型和解题技巧。 首先在N1和N2中&#xff0c;听力题型是一样的。 第一大题「課題理解」 第二大题「ポイント理解」 第三大题「概要理解」 第四大题叫做「即時応答」 第五大题叫做「統合理解」 名字不同&#xff0c;考点和…

秋招如何准备?有什么建议?

秋招&#xff0c;是毕业生最好的求职渠道&#xff0c;没有之一。尽管还有春招&#xff0c;社招......都不如秋招重要&#xff0c;因为秋招的机会更多..... 如何准备秋招&#xff1f; 1、简历很重要 一个好的简历&#xff0c;就是敲门砖&#xff0c;这是你跟企业HR的第一次亲…

python -opencv形态学操作

python -opencv形态学操作 1.服饰和膨胀 1.服饰和膨胀 opencv 腐蚀通过cv2.erode实现&#xff0c;膨胀通过cv2.dilate实现&#xff0c;看一下下面代码&#xff1a; from ctypes.wintypes import SIZE from multiprocessing.pool import IMapUnorderedIterator import cv2 i…

20231122给RK3399的挖掘机开发板适配Android12

20231122给RK3399的挖掘机开发板适配Android12 2023/11/22 9:30 主要步骤&#xff1a; rootrootrootroot-X99-Turbo:~$ tar --use-compress-programpigz -xvpf rk356x_android12_220722.tgz rootrootrootroot-X99-Turbo:~$ cd rk_android12_220722/ rootrootrootroot-X99-Tur…

NOIP2015提高组第二轮T1:能量项链

题目链接 [NOIP2006 提高组] 能量项链 题目描述 在 Mars 星球上&#xff0c;每个 Mars 人都随身佩带着一串能量项链。在项链上有 N N N 颗能量珠。能量珠是一颗有头标记与尾标记的珠子&#xff0c;这些标记对应着某个正整数。并且&#xff0c;对于相邻的两颗珠子&#xff0…

【CodeTop】TOP 100 刷题 11-20

文章目录 11. 二叉树的层序遍历题目描述代码与解题思路 12. 搜索旋转排序数组题目描述代码与解题思路 13. 买卖股票的最佳时机题目描述代码和解题思路 14. 岛屿数量题目描述代码与解题思路 15. 环形链表题目描述代码与解题思路 16. 有效的括号题目描述代码与解题思路 17. 合并两…

呼叫中心自建好还是云外呼好用?

传统的呼叫中心在科技的发展下已经被不适用了&#xff0c;都开始使用起智能化的呼叫中心&#xff0c;一个是自建式呼叫中心&#xff0c;一个是云外呼系统。那自建式呼叫中心与云外呼系统的区别有哪些呢&#xff1f; 1、企业自建呼叫中心 劣势 系统维护更新难&#xff1a;自建…

我的创作纪念日2048天

机缘 在这特殊的日子里&#xff0c;我要庆祝我的 CSDN 创作纪念日——已经坚持了整整2048天&#xff01; 在这2048天里&#xff0c;我经历了很多成长和收获。作为一名技术写手&#xff0c;我投入了大量的时间和精力来分享我的知识和经验。我曾经写过关于数据库、数据同步、数…

AI一点通:卷积神经网络的输出节点大小如何计算?全连接层必要输入大小如何设置

在使用卷积网络&#xff08;CNN&#xff09;时&#xff0c;一个步骤是计算经过卷积和池化步骤后的输出大小&#xff0c;以便我们可以将输出连接到一个完全收集的线性层。 以Pytorch中的一维CNN为例&#xff0c; self.conv1 nn.Conv1d(in_channels1, out_channels64, kernel_s…

python数据结构与算法-10_递归

递归 Recursion is a process for solving problems by subdividing a larger problem into smaller cases of the problem itself and then solving the smaller, more trivial parts. 递归是计算机科学里出现非常多的一个概念&#xff0c;有时候用递归解决问题看起来非常简单…

面对网络渠道低价 品牌如何应对

品牌在发展过程中&#xff0c;会不断拓展自己的销售渠道&#xff0c;网站渠道是顺应消费者习惯的一种销售战场&#xff0c;没有品牌会轻易丢弃这个渠道&#xff0c;但是网络渠道的低价又是很常见的&#xff0c;所以只有及时的治理渠道低价&#xff0c;对应的渠道才会发展越来越…

【shell】shell指令学习

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

【AGC】鸿蒙应用软件包上传问题解析

【问题背景】 近期收到了一些反馈&#xff0c;一些鸿蒙元服务开发者在发布应用市场的过程中&#xff0c;上传.app包时遇到了不同的报错&#xff0c;导致上传失败&#xff0c;下面来看一下这些报错的具体原因&#xff0c;如何正确打包上传。 【问题描述1】 HarmonyOS元服务软件…

排序算法--选择排序

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

逐字节讲解 Redis 持久化(RDB 和 AOF)的文件格式

前言 相信各位对 Redis 的这两种持久化机制都不陌生&#xff0c;简单来说&#xff0c;RDB 就是对数据的全量备份&#xff0c;AOF 则是增量备份&#xff0c;而从 4.0 版本开始引入了混合方式&#xff0c;以 7.2.3 版本为例&#xff0c;会生成三类文件&#xff1a;RDB、AOF 和记…

这7款神仙软件,程序员必备!

如果你是程序员、开发者、网络运维等 IT 从业者日常工作中大家肯定会用到很多网站&#xff0c;今天给大家带来7款压箱底的神仙软件&#xff0c;希望可以帮助有需要的码农朋友实现更高效地办公。 一、Everything 适用&#xff1a;本地文件搜索神器 就是为了极速检索而生,其实…

随机微分方程数值模拟

http://www.lpma-paris.fr/pageperso//lemaire/projets/Papers/NiVi08.pdf See 知乎https://zhuanlan.zhihu.com/p/28628912