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扩展插件Validate—4设置错误提示的样式
Sep 05 Javascript
js加载读取内容及显示与隐藏div示例
Feb 13 Javascript
微信小程序 购物车简单实例
Oct 24 Javascript
JS实现网页抢购功能(触发,终止脚本)
Nov 27 Javascript
vue 项目常用加载器及配置详解
Jan 22 Javascript
微信小程序排坑指南详解
May 23 Javascript
实例详解Node.js 函数
Jun 10 Javascript
angularjs的单选框+ng-repeat的实现方法
Sep 12 Javascript
JavaScript私有变量实例详解
Jan 24 Javascript
Jquery实现获取子元素的方法分析
Aug 24 jQuery
seajs和requirejs模块化简单案例分析
Aug 26 Javascript
vue3 源码解读之 time slicing的使用方法
Oct 31 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
兼容PHP5的PHP目录管理函数库
2008/07/10 PHP
php中3种方法删除字符串中间的空格
2014/03/10 PHP
Yii实现多按钮保存与提交的方法
2014/12/03 PHP
php实现复制移动文件的方法
2015/07/29 PHP
PHP正则替换函数preg_replace()报错:Notice Use of undefined constant的解决方法分析
2017/02/04 PHP
通过修改Laravel Auth使用salt和password进行认证用户详解
2017/08/17 PHP
PHP的PDO大对象(LOBs)
2019/01/27 PHP
greybox——不开新窗口看新的网页
2007/02/20 Javascript
JS之小练习代码
2008/10/12 Javascript
Extjs 几个方法的讨论
2010/01/28 Javascript
JS性能优化笔记搜索整理
2013/08/21 Javascript
jquery mobile事件多次绑定示例代码
2013/09/13 Javascript
JavaScript常用的返回,自动跳转,刷新,关闭语句汇总
2015/01/13 Javascript
快速掌握WordPress中加载JavaScript脚本的方法
2015/12/17 Javascript
Javascript的this用法
2017/01/16 Javascript
es6的数字处理的方法(5个)
2017/03/16 Javascript
jQuery实现页码跳转式动态数据分页
2017/12/31 jQuery
Bootstrap 模态框自定义点击和关闭事件详解
2018/08/10 Javascript
Vue中使用sass实现换肤功能
2018/09/07 Javascript
js 闭包深入理解与实例分析
2020/03/19 Javascript
如何检测JavaScript中的死循环示例详解
2020/08/30 Javascript
Python装饰器基础详解
2016/03/09 Python
Python的几个高级语法概念浅析(lambda表达式闭包装饰器)
2016/05/28 Python
Python selenium 父子、兄弟、相邻节点定位方式详解
2016/09/15 Python
python初学之用户登录的实现过程(实例讲解)
2017/12/23 Python
Python模拟脉冲星伪信号频率实例代码
2018/01/03 Python
如何在django中实现分页功能
2020/04/22 Python
python脚本定时发送邮件
2020/12/22 Python
Internet主要有哪些网络群组成
2015/12/24 面试题
记帐员岗位责任制
2014/02/08 职场文书
幼儿园八一建军节活动方案
2014/08/27 职场文书
领导批评与自我批评范文
2014/10/16 职场文书
组织生活会表态发言材料
2014/10/17 职场文书
投诉信格式范文
2015/07/02 职场文书
2016年中学清明节活动总结
2016/04/01 职场文书
python实现对doc、txt、xls等文档的读写操作
2022/04/02 Python