写在前面

以下所述内容大部分为本人在MDN-Promise,ES6标准入门(第二版)192页开始,和一些博客介绍的消化咀嚼产出,带着粗浅的认识和个人主观偏向,可能理解的不是很到位,想看具体讲解的点下面传送门

  • MDN对Promise介绍
  • ES6标准入门介绍

Promise是什么

按照官方的话来说,Promise是异步编程的一种解决方案,里面通常保存着异步操作事件的结果。以前用嵌套的回调函数解决异步(产生回调地狱),现在用Promise。
所以promise是用来

  • 解决异步的问题
  • 可以并发多个请求,获取并发请求中的数据

Promise有什么

  1. 有三种状态:Pending(进行中)、Resolved(成功,又称Fulfilled)和Rejected(失败),只有两种变化情况,由Pending变为Resolved或Rejected。这些状态只由操作的结果决定,状态一旦发生了改变,就会一直保持,后续回调无法改变。
  2. 有各种内置方法:reject,resolve,then,catch,all,race。

Promise怎么用

基本使用:

var promise = new Promise(function(resolve, reject) {if ( /* 异步操作成功 */ ) {resolve(value);} else {reject(error);}
});

Promise构造函数接收一个函数作为参数,该函数的两个参数分别是resolve和reject。resolve为成功状态,并返回操作结果,reject为失败,且返回错误报告。

Promise实例生成后,可以用then方法(在Promise原型对象内置有),接收两个参数,分别指定Resolved状态和Reject状态的回调函数。成功value,失败为reason或error。

promise.then(function(value) {// success
}, function(error) {// failure
});

完整示例:

function doDelay(time){return new Promise((resolve,reject) => {setTimeout(() => {if(){resolve("xxx")}else{reject("xxx")}}),time})
}doDelay(200).then(value => {},reason => {})

简直不要太简单,下面简单说下Promise其他方法

  • Promise.prorotype.catch() 方法:失败的回调函数,用来指定reject的回调,即使上面resolve报错了,也能执行到catch。
    说明:是then的语法糖,相当于:then(undefined,onRejected)
  • Promise.all 方法:接收一个包含n个promise的数组
    说明:返回一个新的promise,只有所有的promise都成功才成功,只要有一个失败则直接失败且第一个失败的实例作为返回值,一般用在一次加载很多请求,全加载成功在渲染。
  • Promise.race 方法:跟 all 一样,接收一个包含n个promise的数组,只要有一个实例改变状态,该实例就作为返回值返回
    说明:返回一个新的promise,第一个完成的promise的结果状态就是最终的结果状态
  • Promise.allSettled():all的改进版,跟all一样,但是等入参的promise状态都发生了变更才返回,返回一个包含他们状态的Promise。
  • finally():不接收参数,不管Promimse对象最后状态是什么,都会执行的操作。
myPromise()
.then(function(value){console.log('resolved');}, function(err, data){console.log('rejected');}
);//或者
myPromise()
.then(function(data){console.log('resolved');
})
.catch(function(reason){console.log('rejected');
});myPromise()
.all([runAsync1(), runAsync2(), runAsync3()])
.then(function(results){console.log(results);
});

为什么要用Promise

  1. 指定回调函数方式更加灵活
  2. 支持链式调用,不阻塞Promise相关的任何程序,且保持异步关系来解决回调地狱问题

Promise在ajax中的应用(封装)

发送ajax请求的四个步骤

// 1.创建 XMLHttpRequest 对象
var xhr = new XMLHttpRequest();
// 2.设置状态监听函数
xhr.onreadystatechange = function () {// 状态发生变化时,触发回调函数if (xhr.readyState !== 4) return;if (xhr.status === 200) {// 成功:从服务器获取数据,通过responseText拿到响应的文本console.log(xhr.responseText)} else {// 失败,根据响应码判断失败原因new Error(xhr.statusText)}
};
// 3.规定请求的类型、URL 以及是否异步处理请求
xhr.open("GET", url, true);
// 4.将请求发送到服务器
xhr.send();

开发中一般使用promise对ajax进行一个异步封装,具体如下:

// Promise封装Ajax请求
function ajax(method, url, data) {var xhr = new XMLHttpRequest();return new Promise(function (resolve, reject) {xhr.onreadystatechange = function () {if (xhr.readyState !== 4) return;if (xhr.status === 200) {resolve(xhr.responseText);} else {reject(xhr.statusText);}};xhr.open(method, url);xhr.send(data);});
}ajax('GET', '/api/xxx').then(function (data) {// 成功,拿到响应数据console.log(data);
}).catch(function (status) {// 失败,根据响应码判断失败原因new Error(status)
});

对该技术有更深的认识后,在更…


贴个大佬的手写源码

//注:promise对象状态与结果只能改变一次
function Promise(executor){//初始哈Promise状态:pendingthis.PromiseState = "pending"//定义Promise结果this.PromiseResult = nullthis.callbacks = []//用self接收this指向:Promise构造函数const self = this//声明resolve函数function resolve(data){//Promise状态只能改变一次if(self.PromiseState !== "pending") return self.PromiseState = "fulfilled"self.PromiseResult = data//异步任务then方法执行回调self.callbacks.forEach(item => {item.onresolved(data)})}function reject(data){//Promise状态只能改变一次if(self.PromiseState !== "pending") return self.PromiseState = "rejected"self.PromiseResult = data//异步任务then方法执行回调self.callbacks.forEach(item => {item.onrejected(data)})}try {//executor构造器,里面为resolve与reject函数executor(resolve,reject)} catch (error) {//当throw抛出错误时进行捕获执行reject回调reject(error)}}
//定义Promise对象的then方法
Promise.prototype.then = function(onresolved,onrejected){//用self接收this指向:promise对象const self = this//对接收的实参进行判断,如果不是函数则将实参定义为函数并返回该实参if(typeof onresolved !== "function"){onresolved = value => value}//对接收的实参进行判断,如果不是函数则将实参定义为函数并返回该实参if(typeof onrejected !== "function"){onrejected = reason => {throw reason}}//then方法返回值是一个promise对象return new Promise((resolve,reject) => {//声明callback方法实现函数复用function callback(type){try {//判断返回的promise对象的结果let result = type(self.PromiseResult)//如果是promise对象则调用then方法,改变promise状态与结果if(result instanceof Promise){result.then(v => {resolve(v)},r => {reject(r)})}else{//如果不是promise对象则调用resolve函数改变promise对象状态与结果resolve(result)} //如果是抛出错误则调用reject函数改变promise对象状态与结果} catch (error) {reject(error)} }//实现then方法异步执行if(this.PromiseState==="fulfilled"){setTimeout(() => {callback(onresolved)});}//实现then方法异步执行if(this.PromiseState === "rejected"){setTimeout(() => {callback(onrejected)});}//每执行一次then方法当promise状态为pending时就将onresolved与onrejected函数放入callbacks中if(this.PromiseState === "pending"){this.callbacks.push({onresolved:function(){callback(onresolved)},onrejected:function(){callback(onrejected)}})}})
}
//promise对象catch方法的实现,当抛出错误时进行捕获执行onrejected函数
Promise.prototype.catch = function(onrejected){return this.then(undefined,onrejected)
}
//promise内置方法resolve实现
Promise.resolve = function(value){//resolve返回结果是一个promise对象return new Promise((resolve,reject) => {//当传入实参为promise对象时,实参调用then方法改变返回promise对象状态与结果if(value instanceof Promise){value.then(v => {resolve(v)},r => {reject(r)})//如果实参不是promise对象,执行resolve函数改变返回promise对象状态与结果}else{resolve(value)}})
}
//promise内置方法reject实现
Promise.reject = function(reason){//reject返回结果是一个promise对象,直接调用reject方法改变promise结果与状态return new Promise((resolve,reject) => {reject(reason)    })
}
//promise内置方法all实现
Promise.all = function(promises){//all返回结果是一个promise对象return new Promise((resolve,reject) => {//用count进行计数let count = 0let arr = []//遍历promises数组for(let i = 0;i < promises.length;i++){//数组元素调用then方法,执行resolve函数则count自增promises[i].then(v => {count++//用arr接收每一个promise调用resolve结果arr[i] = v//当全部数组元素都执行resolve方法,才会执行resolve方法改变返回promise对象状态与结果if(count == promises.length){resolve(arr)}//只要执行一次reject方法则直接改变返回promise对象状态与结果},r => {reject(r)})}})
}
//promise内置方法race实现
Promise.race = function(promises){//race方法返回结果是一个promise对象return new Promise((resolve,reject) => {for(let i = 0;i < promises.length;i++){//哪一个数组元素先执行resolve或者reject函数即改变返回promise对象结果与状态promises[i].then(v => {resolve(v)},r => {reject(r)})}})
}

小南说 Promise(是什么,有什么,怎么用,为什么)相关推荐

  1. setTimeout、setInterval、promise、async/await的顺序详解(多种情况,非常详细~)

    本文很长,列举的情况很多. 在阅读本文之前,如果您有充足的时间,请新建一个项目与本文一同实践. 每段代码都有对应的解释,但是自己动手尝试印象才会更深哦~ setInterval:表示多久执行一次,需要 ...

  2. C++多线程:异步操作std::async和std::promise

    文章目录 std::async 简介 使用案例 std::promise 简介 成员函数 总结 之前的文章中提到了C++多线程中的异步操作机制 C++ 多线程:future 异步访问类(线程之间安全便 ...

  3. ES6中的Promise详解

    Promise 在 JavaScript 中很早就有各种的开源实现,ES6 将其纳入了官方标准,提供了原生 api 支持,使用更加便捷. 定义 Promise 是一个对象,它用来标识 JavaScri ...

  4. 关于ES6中Promise的应用-顺序合并Promise,并将返回结果以数组的形式输出

    1.Promise 基础知识梳理 创建一个Promise实例 const promise = new Promise(function(resolve, reject) {if (success){r ...

  5. promise实现多个请求并行串行执行

    早上查资料,偶然发现这个话题,发现自己并不会,于是乎,下来研究了一下. 想想之前我们用jquery写请求的时候,要实现请求的串行执行,我们可能是这么做的. $.ajax({url: '',data: ...

  6. 异步编程之Promise(2):探究原理

    异步编程系列教程: (翻译)异步编程之Promise(1)--初见魅力 异步编程之Promise(2):探究原理 异步编程之Promise(3):拓展进阶 异步编程之Generator(1)--领略魅 ...

  7. 自己动手写cpu pdf_自己动手写 Promise

    这段时间在学习Promise,但始终不得要领.为了更好地理解Promise,我决定自己实现一个简易版的Promise,以学习Promise工作原理.该工程名为ToyPromise,仓库地址如下: ht ...

  8. promise 和 async await区别

     什么是Async/Await? async/await是写异步代码的新方式,以前的方法有回调函数和Promise. async/await是基于Promise实现的,它不能用于普通的回调函数. as ...

  9. Promise - js异步控制神器

    微信小程序开发交流qq群   581478349    承接微信小程序开发.扫码加微信. 正文: 首先给来一个简单的demo看看Promise是怎么使用的: <!DOCTYPE html> ...

最新文章

  1. 升级SharePoint场的时候, 运行Configuration Wizard需要有什么顺序么?
  2. 元宇宙该如何发展才不会变为泡沫
  3. Java客户端操作zookeeper:删除节点代码示例
  4. python中MySQLdb的使用
  5. 不要和诱惑较劲,而应离得越远越好。!!!
  6. 不足补0 java_Java Android 开发数字不足位数前面补0
  7. TCP协议的部分解析(3)
  8. gc日志一般关注什么_JVM(23)JVM的Full GC日志
  9. 提高网站第一次加载速度
  10. SPring cloud (3)A Ribbon 负载均衡 配置初步
  11. A non well formed numeric value encountered
  12. JDK下载与安装教程
  13. java基于SSM的宠物医院信息管理系统
  14. 【软件使用】Macbook M1 QuickTime录屏讲解(只录电脑或者同时录电脑和麦克风人声)
  15. Cookie和Session的使用及其案例分析
  16. 从欧盟与韩国实践看智慧城市的开放式治理创新模式
  17. java万年历 节日_用java语言编写一个万年历程序,要求只显示阳历、节日、还有农历年、闰年...
  18. html中创建母版页,自定义“我的网站”母版页
  19. ABeam Insight | 德硕智能制造系列(1):智能制造概览(上)
  20. [渝粤教育] 天津师范大学 创业起跑线 参考 资料

热门文章

  1. 百威啤酒,嬴彻自动驾驶卡车送
  2. linux 获取当前工作路径
  3. Unity中使用插件在地形中制作道路
  4. 2023计算机毕业设计SSM最新选题之java公交电子站牌管理系统软件9430l
  5. 福建省一级计算机考试文字录入,2015福建省机关事业工勤人员计算机文字录入员工作总结.doc...
  6. python批量删缩进_鬼畜小姐姐+野狼disco,十分钟教你如何用Python剪辑一个牛逼的抖音小视频?...
  7. 常见的浏览器有哪些?其核心分别是什么 ?
  8. 2022-09-17青少年软件编程(C语言)等级考试试卷(四级)解析
  9. 面向对象多项式求导总结
  10. 6-23 sdust-Java-可实现多种排序的Book类