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 图片 上一张 下一张 链接效果(续篇)
Apr 20 Javascript
javascript日期转换 时间戳转日期格式
Nov 05 Javascript
Js-$.extend扩展方法使方法参数更灵活
Jan 15 Javascript
jquery 实现两Select 标签项互调示例代码
Sep 25 Javascript
鼠标事件的screenY,pageY,clientY,layerY,offsetY属性详解
Mar 12 Javascript
浅谈addEventListener和attachEvent的区别
Jul 14 Javascript
原生js实现倒计时--2018
Feb 21 Javascript
AngularJS之页面跳转Route实例代码
Mar 10 Javascript
JavaScript纯色二维码变成彩色二维码
Jul 23 Javascript
JS实现微信摇一摇原理解析
Jul 22 Javascript
基于Web Audio API实现音频可视化效果
Jun 12 Javascript
JavaScript实现多层颜色选项卡嵌套
Sep 21 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 递归效率分析
2009/11/24 PHP
深入理解用mysql_fetch_row()以数组的形式返回查询结果
2013/06/05 PHP
PHP按行读取文件时删除换行符的3种方法
2014/05/04 PHP
PHP中异常处理的一些方法整理
2015/07/03 PHP
PHP附件下载中文名称乱码的解决方法
2015/12/17 PHP
CI框架简单邮件发送类实例
2016/05/18 PHP
php遍历目录下文件并按修改时间排序操作示例
2019/07/12 PHP
jquery 弹出层实现代码
2009/10/30 Javascript
Google AJAX 搜索 API实现代码
2010/11/17 Javascript
Jquery加载时从后台读取数据绑定到dropdownList实例
2013/06/09 Javascript
jQuery固定浮动侧边栏实现思路及代码
2014/09/28 Javascript
node.js中的path.extname方法使用说明
2014/12/09 Javascript
深入理解JavaScript系列(47):对象创建模式(上篇)
2015/03/04 Javascript
Vuejs第八篇之Vuejs组件的定义实例解析
2016/09/05 Javascript
bootstrap实现点击删除按钮弹出确认框的实例代码
2018/08/16 Javascript
实例分析vue循环列表动态数据的处理方法
2018/09/28 Javascript
JS实现手写 forEach算法示例
2020/04/29 Javascript
解决vue数据不实时更新的问题(数据更改了,但数据不实时更新)
2020/10/27 Javascript
[02:23]2016国际邀请赛中国区预选赛wings晋级之路
2016/06/29 DOTA
python非递归全排列实现方法
2017/04/10 Python
Python 实现网页自动截图的示例讲解
2018/05/17 Python
PyCharm代码整体缩进,反向缩进的方法
2018/06/25 Python
Pycharm 2020年最新激活码(亲测有效)
2020/09/18 Python
Python输出指定字符串的方法
2020/02/06 Python
Python Opencv中用compareHist函数进行直方图比较对比图片
2020/04/07 Python
如何基于python实现不邻接植花
2020/05/01 Python
python将dict中的unicode打印成中文实例
2020/05/11 Python
mac安装python3后使用pip和pip3的区别说明
2020/09/01 Python
军校制空专业毕业生自我鉴定
2013/11/16 职场文书
学习方法演讲稿
2014/05/10 职场文书
预备党员学习十八届三中全会精神思想汇报
2014/09/13 职场文书
奔腾年代观后感
2015/06/09 职场文书
2016年“七一建党节”广播稿
2015/12/18 职场文书
干货干货!2019最新优秀创业计划书
2019/03/21 职场文书
Python一行代码实现自动发邮件功能
2021/05/30 Python
漫画「处刑少女的生存之道」第3卷封面公开
2022/03/21 日漫