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

<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. 华为云NFT云宝限量开抢,区块链技术为你的数字资产保驾护航

    摘要:正是有这些底层的区块链技术支撑,才能让我们真正的"拥有"独属于自己的NFT数字资产. 本文分享自华为云社区<华为云独家NFT限量开抢,背后的这些技术你都知道吗?> ...

  2. 【django-vue】七牛云上传视频 搜索接口 支付宝sdk二次封装 下单接口 前端支付页面 支付成功回调接口

    目录 上节回顾 课程详情接口 choice字段 今日内容 1 文件存储 1.1 七牛云上传文件 2 搜索导航栏 2.1 Header.vue 3 搜索接口 4 搜索页面 5 支付宝支付介绍 5.1 支 ...

  3. #2051:Bitset(进制转化)

    Problem Description Give you a number on base ten,you should output it on base two.(0 < n < 10 ...

  4. Spring 学习笔记(5)AOP

    本文介绍 Spring 中 AOP 的原理及使用方式. Spring AOP 简介 如果说 IoC 是 Spring 的核心,那么面向切面编程就是 Spring 最为重要的功能之一了,在数据库事务中切 ...

  5. UVA - 10391:Compound Words (字符串水题)

    题目大意 给定若干单词,按字典序输出由两个单词拼接而成的单词 思路分析 用set存储所有单词,枚举每个单词word,遍历word的所有左右子串组合情况,若左右子串均在set中,说明符合题意.时间复杂度 ...

  6. ​iOS Class Guard github用法、工作原理和安装详解及使用经验总结

    ​iOS Class Guard github用法.工作原理和安装详解及使用经验总结 iOS Class Guard是一个用于OC类.协议.属性和方法名混淆的命令行工具.它是class-dump的扩展 ...

  7. python进阶(8)--测试函数与类

    一.测试函数(unittest) 1.源文件方法(name_function.py): def get_formatted_name(first,last): """生成 ...

  8. 入门 shell 从脚本开始 - lazy_find

    编写脚本实现在指定文件路径下查找文件夹或文件名.   脚本如下: #!/bin/sh # lazy find # GNU All-Permissive License # Copying and di ...

  9. 深入理解Kafka核心设计及原理(一):初识Kafka

    转载请注明出处: 1.1 kafka简介 Kafka 起初是由 Linkedin 公司采用 Scala 语言开发的一个多分区.多副本且基于 ZooKeeper协调的分布式消息系统,现己被捐献给 Apa ...

  10. spring启动流程 (3) BeanDefinition详解

    BeanDefinition在Spring初始化阶段保存Bean的元数据信息,包括Class名称.Scope.构造方法参数.属性值等信息,本文将介绍一下BeanDefinition接口.重要的实现类, ...