看看下面这一段代码返回来的是什么???

<body>
<script type="text/javascript">
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('ok');
}, 1000)
}) const res=p.then(res => {
console.log(res)
}, err => {
console.log(err)
})
// 根据promise返回来的结果规律,
// 由于我什么都没有写,返回的应该是undefined
// 它返回的的是非Promise类型的数据,如undefined; 数字,字符串。
// 那么 result就是一个成功的Promise
console.log( 'res', res )
</script>
</body>

我们现在写的promise

<script src="./Promise.js"></script>
<body>
<script type="text/javascript">
let p = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('ok');
}, 1000)
}) const res=p.then(res => {
console.log(res)
}, err => {
console.log(err)
})
console.log( 'res', res )
</script>
</body>

结果

{
PromiseStatus:"pending"
PromiseValue:null
}

为啥是padding

当我们的代码从上往下执行的时候,
会走进
if (this.PromiseStatus === "pending") {
// 这个是保存回调函数
this.callBack.push({
onResolve: onResolve,
onReject: onReject,
});
}
这里;
我们知道这里并没有去调用 resolve, reject
所以返回来的状态一定是一个padding

如何处理这个问题

const self=this; // new add
if (this.PromiseStatus === "pending") {
// 这个是保存回调函数 new add
this.callBack.push({
// 执行成功的回调函数,改变里面的状态
// 下面这些都是根据promise返回结果的结论来写的
onResolve: function () {
let result = onResolve(self.PromiseStatus)
// 判断是否是promise,根据是否是promise返回不同的状态
if (result instanceof Promise) {
// 如果是一个promise就可以去调用then方法
result.then(s => {
resolve(s)
}, e => {
reject(e)
})
} else {
// 如果不是promise直接返回成功
resolve(result)
} },
onReject: function () {
let result = onReject(self.PromiseStatus)
// 判断是否是promise,根据是否是promise返回不同的状态
if (result instanceof Promise) {
// 如果是一个promise就可以去调用then方法
result.then(s => {
resolve(s)
}, e => {
reject(e)
})
} else {
// 如果不是promise直接返回成功
resolve(result)
}
}
});
}

现在虽然可以返回正常的结果和状态,但是抛出异常是有问题的哈,使用try catch

完整版本

function Promise(executor) {
const self = this;
function resolve(data) {
// 如果状态发生改变就直接返回(为了让Promise的状态只发生一次改变);
if (self.PromiseStatus !== "pending") return;
self.PromiseStatus = "resolved";
self.PromiseValue = data; // 调用成功的回调函数进行遍历
self.callBack.forEach((item) => {
item.onResolve(data);
});
}
// 同样声明成为一个函数;修改状态
function reject(err) {
// 如果状态发生改变就直接返回(为了让Promise的状态只发生一次改变);
if (self.PromiseStatus !== "pending") return;
self.PromiseStatus = "rejected";
self.PromiseValue = err;
// 调用失败的回调函数数进行遍历
self.callBack.forEach((item) => {
item.onReject(err);
});
}
this.PromiseStatus = "pending";
this.PromiseValue = null;
// 声明属性 new add
this.callBack = [];
// 对异常进行处理;使用try catch
try {
executor(resolve, reject);
} catch (err) {
reject(err);
}
}
// 自定义封装then方法执行回调
Promise.prototype.then = function (onResolve, onReject) {
// new add注意this的指向
const self = this;
// 返回一个promise对象
return new Promise((resolve,reject)=>{
if (this.PromiseStatus === "resolved") {
try{
let chenggong= onResolve(this.PromiseValue);
if(chenggong instanceof Promise){
// 如果你是一个Promise,那么可以去调用这个then方法
chenggong.then(v=>{
resolve(v);
},r=>{
reject(r);
})
}else{
// 不是Promise类型的对象
// 结果的对象状态【成功】
resolve(chenggong)
}
}catch(e){
reject(e);
}
// 获取回调函数的执行结果
}
if (this.PromiseStatus === "rejected") {
onReject(this.PromiseValue);
}
// 如果是pending的状态
if (this.PromiseStatus === "pending") {
// 这个是保存回调函数 new add
this.callBack.push({
// 执行成功的回调函数,改变里面的状态
// 下面这些都是根据promise返回结果的结论来写的
onResolve: function () {
//对抛出的异常进行处理哈
try {
let result = onResolve(self.PromiseStatus)
// 判断是否是promise,根据是否是promise返回不同的状态
if (result instanceof Promise) {
// 如果是一个promise就可以去调用then方法
result.then(s => {
resolve(s)
}, e => {
reject(e)
})
} else {
// 如果不是promise直接返回成功
resolve(result)
}
} catch (error) {
reject(error)
} },
onReject: function () {
//对抛出的异常进行处理哈
try {
let result = onReject(self.PromiseStatus)
// 判断是否是promise,根据是否是promise返回不同的状态
if (result instanceof Promise) {
// 如果是一个promise就可以去调用then方法
result.then(s => {
resolve(s)
}, e => {
reject(e)
})
} else {
// 如果不是promise直接返回成功
resolve(result)
}
} catch (error) {
reject(error)
} }
});
}
})
};

手写promise异步状态修改then方法返回来的结果的更多相关文章

  1. 手写Promise看着一篇就足够了

    目录 概要 博客思路 API的特性与手写源码 构造函数 then catch Promise.resolved Promise.rejected Promise.all Promise.race 概要 ...

  2. 手写Promise A+ 规范

    基于ES6语法手写promise A+ 规范,源码实现 class Promise { constructor(excutorCallBack) { this.status = 'pending'; ...

  3. 手写Promise中then方法返回的结果或者规律

    1. Promise中then()方法返回来的结果或者规律 我们知道 promise 的 then 方法返回来的结果值[result]是由: 它指定的回调函数的结果决定的 2.比如说下面这一段代码 l ...

  4. 手写promise

    写在前面: 在目前的前端分开中,我们对于异步方法的使用越来越频繁,那么如果处理异步方法的返回结果,如果优雅的进行异步处理对于一个合格的前端开发者而言就显得尤为重要,其中在面试中被问道最多的就是对Pro ...

  5. [转]史上最最最详细的手写Promise教程

    我们工作中免不了运用promise用来解决异步回调问题.平时用的很多库或者插件都运用了promise 例如axios.fetch等等.但是你知道promise是咋写出来的呢? 别怕-这里有本promi ...

  6. 手写Promise简易版

    话不多说,直接上代码 通过ES5的模块化封装,向外暴露一个属性 (function(window){ const PENDING = 'pending'; const RESOLVED = 'fulf ...

  7. 前端面试题之手写promise

    前端面试题之Promise问题 前言 在我们日常开发中会遇到很多异步的情况,比如涉及到 网络请求(ajax,axios等),定时器这些,对于这些异步操作我们如果需要拿到他们操作后的结果,就需要使用到回 ...

  8. 手写 Promise 符合 Promise/A+规范

    异步编程是前端开发者必需的技能,过去管理异步的主要机制都是通过函数回调,然而会出现像“回调地狱”这样的问题.为了更好的管理回调,ES6 增加了一个新的特性 Promise.Promise 是 ES7 ...

  9. (手写识别) Zinnia库及其实现方法研究

    Zinnia库及其实现方法研究 (转) zinnia是一个开源的手写识别库.采用C++实现.具有手写识别,学习以及文字模型数据制作转换等功能. 项目地址 [http://zinnia.sourcefo ...

  10. 手写 Promise

    在上一章节中我们了解了 Promise 的一些易错点,在这一章节中,我们会通过手写一个符合 Promise/A+ 规范的 Promise 来深入理解它,并且手写 Promise 也是一道大厂常考题,在 ...

随机推荐

  1. 复杂查询so easy ,GaussDB(for Cassandra)推Lucene引擎全新解决方案

    摘要:复杂查询so easy!GaussDB(for Cassandra)新特性来袭. 本文分享自华为云社区<来了!GaussDB(for Cassandra)新特性亮相>,作者:Gaus ...

  2. Jenkins 手动安装插件

    手动装插件太麻烦了,还是装最新版 Jenkins 配置源 然后在Manage Plugins -->Manage Plugins -->Advanced 中,把Update Site修改为 ...

  3. 机器学习周刊 第4期:动手实战人工智能、计算机科学热门论文、免费的基于ChatGPT API的安卓端语音助手、每日数学、检索增强 (RAG) 生成技术综述

    LLM开发者必读论文:检索增强(RAG)生成技术综述! 目录: 1.动手实战人工智能 Hands-on Al 2.huggingface的NLP.深度强化学习.语音课 3.Awesome Jupyte ...

  4. L2-029 特立独行的幸福 (25分) (简单循环 + 素数筛)

    对一个十进制数的各位数字做一次平方和,称作一次迭代.如果一个十进制数能通过若干次迭代得到 1,就称该数为幸福数.1 是一个幸福数.此外,例如 19 经过 1 次迭代得到 82,2 次迭代后得到 68, ...

  5. 区分开发环境和生产环境webpack

  6. JVM 性能调优 及 为什么要减少 Full GC

    本文为博主原创,未经允许不得转载: 系统上线压测,需要了解系统的瓶颈以及吞吐量,并根据压测数据进行对应的优化. 对压测进行 JVM 性能优化,有两条思路: 第一种情况 : 使用压测工具 jmeter  ...

  7. 基于AHB_BUS SRAM控制器的设计-01

    基于AHB Bus SRAM控制器的设计 1.课程目标 接到一个需求要设计SRAM或者I-cache等,需要问后端要一个Memory Memory Compiler是由后端工程师完成的,Memory ...

  8. AMBA总线介绍-02

    AMBA总线介绍 1 HSIZE AHB总线的地址位宽和数据位宽一般都是32bit,一个字节8bit,一个字节占用一个地址空间,但当一个32bit的数据写入一个存储器中或者从一个存储器中读取,32bi ...

  9. 【rt-thread】移植touchgfx时出现如下错误和现象

    [问题描述] 基于cubemx生成的touchgfx工程,移植入rt-threadkeil编译报重复定义 加载到文件组中的文件奇妙的出现了 Src_ .Device_.i2c_.Keil_  前缀,这 ...

  10. PolarD&N2023秋季个人挑战赛—Misc全解

    签个到叭 题目信息 压缩包带密码,放到010查看PK头错误,改回去.. 解压后得到 562+5Yiw5Lmf5LiN6IO96L+Z5LmI566A5Y2V5ZGA77yM5b+r5p2l55yL55 ...