写点什么

【Promise 源码学习】第一篇 - Promise 简介

用户头像
Brave
关注
发布于: 刚刚

一,前言


上一篇,完成了 Promise 源码学习的目录;

本篇,主要对 Promise 进行简单的概括介绍;


二,Promise 简介


  • Promise 是一个类或构造函数,是 JS 原生提供的,通过实例化 Promise 完成预期的异步任务处理;

  • Promise 是一个能够获取异步操作消息的对象;译为承诺,表示会在一段时间后返回处理结果;

  • Promise 是一种异步编程的解决方案,被 ES6 列为正式规范,提供了原生 Promise 对象;

  • Promise 能够接收一个异步请求,在提供的 then/catch 方法中拿到异步请求的处理结果;

  • Promise 支持链式调用,通过链式调用的方式能够将异步请求的结果以同步的方式进行处理;


三,Promise 基本使用


Promise 对异步操作进行包装:

// 创建var promise = new Promise((resolve, reject)=>{  setTimeout(()=>{    if("异步请求成功"){      resolve('ok');    } else {      reject('error')    }  }, 2000);});
// 使用promise.then(data=>{ console.log(data);}).catch(error=>{ console.log(error);});
复制代码


从示例中能够看出:

  • Promise 的参数是一个回调函数,其中包含了两个参数:resolve 和 reject;

  • 当异步操作成功时,通过调用 resolve 返回异步操作的成功结果;

  • 当异步操作失败时,通过调用 reject 返回异步操作的失败结果;

  • 异步操作成功时,进入 then 处理后续操作;

  • 异步操作失败时,进入 catch 处理后续操作;(当前示例是这样的,当 then 函数的第二个回调定义时,也可以捕捉失败操作,这个机制后面会详细解释)


但实际上,除以上示例体现出来的部分,Promise 还具有更多特性,理解并掌握这些特性是用好 Promise 的基础;


四,Promise 和 callback 对比


callback 方式处理异步操作:

function async(callback){    setTimeout(function(){        callback("异步操作完成");    }, 1000);}
async(function(data){ console.log(data);});
复制代码


Promise 和 callback 的本质区别,就是控制权反转


  • 在 callback 模式下,回调函数的执行控制权在封装层:

  • 业务层将回调函数定义传递给封装层

  • 封装层在任务结束时执行了回调函数;

  • 业务层并没有调用回调函数,甚至连调用的代码都看不到;

  • 在 Promise 模式下,回调函数的执行控制权在业务层:

  • 业务层并没有把回调函数直接传递给封装层(Promise 对象内部);

  • 封装层在任务结束时,并不知道要执行的回调,只能通过 resolve 或 reject 通知到业务层,由业务层在 then() 或 reject() 中控制回调执行;

  • 业务层不仅能看到回调函数的调用代码,还能对其进行修改;


五,Promise 的作用


pomise 可以说(主要)是为了解决程序异步处理而生的;

  • Promise 不仅解决了异步回调的多层嵌套,即“回调地狱”问题;

  • 更重要的,Promise 提供了更完整、更强大的异步解决方案;通过 Promise 构造函数上提供的方法,实现对 Promise 批量操作的支持,如:all、race、any、allSettled 等;


六,Promise 的重要性


目前,Promise 在前端领域的应用中,几乎是无处不在的,已经成为了前端开发中最重要的技能之一;


Promise 也是前端面试的高频考察点:考察方式多样化,考察内容可深可浅;同时,也能够关联出很多实际应用场景;因此,熟练地掌握 promise 是每个前端开发的必备能力;


七,Promise 的兼容性

1,兼容性介绍


Promise 属于 ES6 规范内容,浏览器支持情况可查看 Can I useMDN




  • Chrome 浏览器 - 支持

  • 360 浏览器 - 兼容模式下支持

  • IE 内核浏览器 - 不支持


2,解决方案


  • bluebird.js在项目中使用 Promsie 对象,可以使用第三方插件 bluebird.js;

bluebird 对 ES6 原生 Promise 进行封装,解决了浏览器兼容性问题;

  • es6-promise使用 es6-promise 也可以解决 IE 下不支持 Promise 的问题;



八,Promise 使用场景


JS 的异步处理可以说是无处不在的,比如:nodejs 和小程序所提供的 API 都是基于回调的;

而这也就导致了开发中时常出现“回调地狱”的坏味道(团队 CodeReview 关注点):

const fs = require('fs');
fs.readFile('./a.txt','utf8',(err,data)=>{ if(err) return err console.log(data) fs.readFile('./b.txt','utf8',(err,data)=>{ if(err) return err console.log(data) fs.readFile('./c.txt','utf8',(err,data)=>{ if(err) return err console.log(data) fs.readFile('./d.txt','utf8',(err,data)=>{ if(err) return err console.log(data) // ...回调地狱 }) }) })})
复制代码


为了解决类似这种异步操作带来的问题,使代码编写更加优雅且更具可读性,Promise 作为前端异步编程的解决方案诞生了;


上边的代码使用 Promise 进行包装处理,如下:

const fs = require('fs');
// 使用 Promise 封装处理 fs.readFilefunction readFile(filePath, encoding) { return new Promise((resolve, reject) => { fs.readFile(filePath, encoding, (err, data) => { if (err) return reject(err) //失败 resolve(data) // 成功 }) });}
// 使用方式readFile('./a.txt','utf8').then((data) => { console.log(data) return readFile('./b.txt','utf8')}).then((data) => { console.log(data) return readFile('./c.txt','utf8')}).then((data) => { console.log(data) return readFile('./d.txt','utf8')}).then((data) => { console.log(data)})
复制代码


这种将异步回调包装成为 Promise 的处理方式也叫 Promisify,常用于 nodejs、小程序场景,使异步代码更简洁;


  • 备注:使用类库时仔细查看官方说明,目前很多类库都支持返回 Promise 实例,应尽量避免在外部进行重复包装;部分类库既支持 callback 也支持 Promise 形式;


九,Promise 优缺点


  • 优点

  • 优化异步代码,解决“回调地狱”问题,增强代码的可读性、可维护性;

  • Promise 对象提供统一的接口,使得控制异步操作更加容易;

  • 通过 catch 方法对异常进行统一的捕获处理;

  • 缺点

  • 无法取消 Promise,一旦创建它就会立即执行,无法中途取消;

  • 如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部;

  • 当处于 Pending 状态时,是无法得知目前进展到哪一个阶段(刚刚开始还是即将完成);


十,结尾


本篇,对 Promise 进行了简单介绍,主要涉及以下几个点:


  • Promise 简介和基本使用;

  • Promise 和 callback 对比;

  • Promise 的重要性和作用;

  • Promise 使用场景:Promisify 封装;

  • Promise 的优缺点、兼容性;


备注:本篇的定位仅仅是简单的认识和了解 Promise,并未涉及深入的介绍和分析,比如:Promise 的状态、执行顺序、链式调用、api 使用、异常处理等;


下一篇,将结合示例对 Promise 进行相关功能介绍与特性分析;


维护日志

  • 20211019

  • 更新部分示例代码,更符合相关知识点;

  • 添加 promise 兼容性部分;

  • 更新结尾部分、文章摘要;

  • 20211024

  • 扩充部分内容;

  • 20211025

  • 重新梳理大纲,调整一二级标题、扩充相关内容;

  • 修改文章标题、摘要;

用户头像

Brave

关注

还未添加个人签名 2018.12.13 加入

还未添加个人简介

评论

发布
暂无评论
【Promise 源码学习】第一篇 - Promise 简介