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

<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. MongoDB 占用CPU资源过高

    情况如下 db.currentOp() 发现有全表扫描 将 Collscan 对应的 Collection 建索引 db.Table1.createIndex({"DataTime" ...

  2. 不使用kvm的qemu虚拟化

    本文记录的是在某些机器上并不支持kvm虚拟化,单纯使用qemu来完成虚拟机的创建和管理. 系统版本:centos 7 qemu版本:4.2 首先说明一下qemu和kvm的关系: qemu 是一个模拟器 ...

  3. 【JAVA基础】加密算法

    加密算法 MD5三次加密 package com.cy.store.service.impl; import com.cy.store.entity.User; import com.cy.store ...

  4. C++ Idioms Pimpl

    References C++ Coding Standard 這本書的中文版不知道是不是翻譯問題,還是原作就有這種傾向,有些咬文嚼字的很不好懂. Exceptional C++ 這本比上面那本容易理解 ...

  5. 通过 Homebrew 在 Mac OS X 上安装和配置 Redis

    通过使用 Homebrew,可以大大降低在 Mac OS X 上设置和配置开发环境的成本. 让我们安装 Redis. $ brew install redis 安装后,我们将看到一些有关配置注意事项的 ...

  6. vue 状态管理 五、Module用法

    系列导航 vue 状态管理 一.状态管理概念和基本结构 vue 状态管理 二.状态管理的基本使用 vue 状态管理 三.Mutations和Getters用法 vue 状态管理 四.Action用法 ...

  7. <vue 基础知识 3、v-bind使用>

    代码结构 一.     v-bind基本使用 1.效果 2.代码 01-v-bind基本使用.html <!DOCTYPE html> <html lang="en&quo ...

  8. vue 使用print.js实现前端打印功能

    https://blog.csdn.net/cccdf_jjj/article/details/99563682 插件vue-print-nb实现前端打印当前页面功能 https://blog.csd ...

  9. java进阶(9)--数组

    一.基本概念: 1.数字为引用数据类型 2.数组实际上是一个容器,可以同时容纳多个元素 3.数组可存储基本数据类型,也可以存储引用数据类型的数据 4.数组一旦创建.长度不可变.且数组中元素类型必须统一 ...

  10. LeetCode-Go:一个使用 Go 语言题解 LeetCode 的开源项目

    在中国的 IT 环境里,大多数场景下,学习算法的目的在于通过笔试算法题. 但算法书林林总总,有时候乱花渐欲迷人眼. 杜甫有诗云:读书破万卷,下笔如有神.不管选择哪本书,只要深入学习,分层次,逐层进阶, ...