javascript下使用Promise封装FileReader


Posted in Javascript onFebruary 19, 2016

Promise 在处理异步的时候是个很好的选择,可以减少嵌套层次,让代码更好读,逻辑更清晰。ES6 将其加入规范,jQuery 3.0 也修改实现向规范靠拢(3.0 发布公告)。一些新增元素比如 .fetch() 原生就 “thenable”,不过大多数以往的 API 还要依赖回调,这个时候,我们只要将它们重新封装,就能避开嵌套陷阱,享受 Promise 带来的愉悦体验。

Promise 一般用法
先来看下 Promise 的一般用法。

// 声明 Promise 对象
var p = new Promise(function (resolve, reject) {
 // 不管啥时候,该执行then了,就调用 resolve
 setTimeout(function () { 
  resolve(1);
 }, 5000);

 // 或者不管啥问题,就调用 reject
 if (somethingWrong) {
  reject('2');
 }   
});
  
// 使用 Promise 对象
p.then(function (num) {
 // 对应上面的 resolve
 console.log(num); // 1
}, function (num) {
 // 对应上面的 reject
 console.log(num); // 2
});

Promise 的驱动模型并不复杂:任何操作,假定它只有两个结果,成功或者失败。那么只需要在合适的时间调用合适的程序,进入合适的后续步骤即可。.then() 顾名思义,就是下一步的意思,当前面的 Promise 有了结果——即调用 resolve 或者 reject——之后,就启动对应的处理函数。

Promise 实例创建后就会开始执行,判定结果需要我们自己来,比如加载成功,或者满足某个条件,等等。通过串联 .then() 则可以完成一系列操作。每次调用 .then() 都会创建一个新的 Promise 实例,它会静静等待前面的实例状态改变后再开始执行。

封装 FileReader
接下来开始封装。思路很简单,FileReader 除了提供各种 read 方法,还有几个事件钩子,其中 onerror 和 onload 很明显可以作为判断任务是否完成的依据。加载成功的话,就需要用到文件内容,所以将文件或文件内容传递到下一步也十分必要。

最后完成的代码如下:

function reader (file, options) {
 options = options || {};
 return new Promise(function (resolve, reject) {
  let reader = new FileReader();

  reader.onload = function () {
   resolve(reader);
  };
  reader.onerror = reject;

  if (options.accept && !new RegExp(options.accept).test(file.type)) {
   reject({
    code: 1,
    msg: 'wrong file type'
   });
  }

  if (!file.type || /^text\//i.test(file.type)) {
   reader.readAsText(file);
  } else {
   reader.readAsDataURL(file);
  }
 });
}

为了能真正派上用场,里面还有一些验证文件类型的操作,不过跟本文主旨无关,略过不表。这段代码的核心是创建一个 Promise 对象,等待 FileReader 读取完成后调用 resolve 方法,或者出现问题时调用 reject 方法。

使用刚才封装好的函数
接下来就可以在项目中使用了:

reader(file)
 .then(function (reader) {
  console.log(reader.result);
 })
 .catch(function (error) {
  console.log(error);
 });

.then() 支持两个参数,第一个在 Promise 成功时启动,第二个自然在失败时启动。用 .catch() 可以实现同样地效果。Promise 的好处除了可读性更佳以外,返回的 Promise 对象还可以任意传递,继续进行链式调用,有很大想象空间。

继续 .then()
于是我们不妨串联更多操作(本来想写个断点续传的,回头再说吧):

全选复制放进笔记reader(file)

.then(function (reader) {
  return new Promise(function (resolve, reject) {
   // 就随便暂停个5秒吧……
   setTimeout(function () {
    resolve(reader.result); 
   }, 5000);
  });
 })
 .then(function (content) {
  console.log(content);
 });

以上就是本文的全部内容,希望对大家的学习有所帮助。

Javascript 相关文章推荐
jquery 操作两个select实现值之间的互相传递
Mar 07 Javascript
JavaScript调用ajax获取文本文件内容实现代码
Mar 28 Javascript
jQuery中map()方法用法实例
Jan 06 Javascript
jQuery实现点击图片翻页展示效果的方法
Feb 16 Javascript
Bootstrap三种表单布局的使用方法
Jun 21 Javascript
基于CSS3和jQuery实现跟随鼠标方位的Hover特效
Jul 25 Javascript
详解Jquery的事件操作和文档操作
Dec 19 Javascript
jQuery插件autocomplete使用详解
Feb 04 Javascript
JavaScript实现三级联动菜单实例代码
Jun 26 Javascript
使用JavaScript实现在页面中显示距离2017年中秋节的天数
Sep 26 Javascript
React组件中的this的具体使用
Feb 28 Javascript
vue任意关系组件通信与跨组件监听状态vue-communication
Oct 18 Javascript
javascript每日必学之循环
Feb 19 #Javascript
jQuery实现简单的DIV拖动效果
Feb 19 #Javascript
JavaScript深度复制(deep clone)的实现方法
Feb 19 #Javascript
百度坐标(BD09)、国测局坐标(火星坐标,GCJ02)、和WGS84坐标系之间的转换
Feb 19 #Javascript
基于JavaScript实现弹出框效果
Feb 19 #Javascript
jQuery on()绑定动态元素出现的问题小结
Feb 19 #Javascript
学习javascript文件加载优化
Feb 19 #Javascript
You might like
php生成随机密码的几种方法
2011/01/17 PHP
关于PHP的curl开启问题探讨
2014/04/08 PHP
PHP图片等比例缩放生成缩略图函数分享
2014/06/10 PHP
php实现Mongodb自定义方式生成自增ID的方法
2015/03/23 PHP
php提高网站效率的技巧
2015/09/29 PHP
Yii中CGridView禁止列排序的设置方法
2016/07/12 PHP
PHP实现上传图片到 zimg 服务器
2016/10/19 PHP
PHP实现的链式队列结构示例
2017/09/15 PHP
PHP使Laravel为JSON REST API返回自定义错误的问题
2018/10/16 PHP
jquery判断checkbox(复选框)是否被选中的代码
2010/10/20 Javascript
Javascript开发之三数组对象实例介绍
2012/11/12 Javascript
js post提交调用方法
2014/02/12 Javascript
javascript正则表达式中的replace方法详解
2015/04/20 Javascript
实现微信小程序的wxml文件和wxss文件在webstrom的支持
2017/06/12 Javascript
jQuery实现的简单日历组件定义与用法示例
2018/12/24 jQuery
浅谈redux, koa, express 中间件实现对比解析
2019/05/23 Javascript
JavaScript和TypeScript中的void的具体使用
2019/09/12 Javascript
uni-app微信小程序登录并使用vuex存储登录状态的思路详解
2019/11/04 Javascript
解决vue项目F5刷新mounted里的函数不执行问题
2019/11/05 Javascript
js面向对象之实现淘宝放大镜
2020/01/15 Javascript
微信小程序自定义tabBar的踩坑实践记录
2020/11/06 Javascript
Python标准库之sqlite3使用实例
2014/11/25 Python
使用Python脚本来获取Cisco设备信息的示例
2015/05/04 Python
Python简单实现enum功能的方法
2016/04/25 Python
python实现用户答题功能
2018/01/17 Python
python爬取网页内容转换为PDF文件
2020/07/28 Python
django模板加载静态文件的方法步骤
2019/03/01 Python
python 堆和优先队列的使用详解
2019/03/05 Python
人力资源管理毕业生自荐信
2013/11/21 职场文书
小学生家长评语集锦
2014/01/30 职场文书
四个太阳教学反思
2014/02/01 职场文书
2014最新开业庆典策划方案(5篇)
2014/09/15 职场文书
2014年信用社工作总结
2014/11/25 职场文书
2015医德医风个人工作总结
2015/04/02 职场文书
CSS 圆形进度栏
2021/04/06 HTML / CSS
Ruby序列化和持久化存储 Marshal和Pstore介绍
2022/04/18 Ruby