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 相关文章推荐
区分JS中的undefined,null,"",0和false
Mar 08 Javascript
javascript之解决IE下不渲染的bug
Jun 29 Javascript
文件编码导致jquery失效的解决方法
Jun 26 Javascript
javascript实现iframe框架延时加载的方法
Oct 30 Javascript
微信小程序使用第三方库Underscore.js步骤详解
Sep 27 Javascript
JS实现快速的导航下拉菜单动画效果附源码下载
Nov 01 Javascript
Bootstrap基本插件学习笔记之按钮(21)
Dec 08 Javascript
详解Python中logging日志模块在多进程环境下的使用
Dec 26 Javascript
vue init失败简单解决方法(终极版)
Dec 22 Javascript
JS中call和apply函数用法实例分析
Jun 20 Javascript
关于AOP在JS中的实现与应用详解
May 06 Javascript
vue实现按需加载组件及异步组件功能
May 27 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
AJAX的使用方法详解
2017/04/29 PHP
js调用flash的效果代码
2008/04/26 Javascript
12个非常有创意的JavaScript小游戏
2010/03/18 Javascript
javascript 面向对象的JavaScript类
2010/05/04 Javascript
js获取控件位置以及不同浏览器中的差别介绍
2013/08/08 Javascript
在Javascript中处理字符串之big()方法的使用
2015/06/08 Javascript
学习JavaScript设计模式(继承)
2015/11/26 Javascript
信息页文内画中画广告js实现代码(文中加载广告方式)
2016/01/03 Javascript
Bootstrap3下拉菜单的实现
2017/02/22 Javascript
浅析vue component 组件使用
2017/03/06 Javascript
关于angular js_$watch监控属性和对象详解
2017/04/24 Javascript
Vue2单一事件管理组件通信
2017/05/09 Javascript
JavaScript登录验证基础教程
2017/11/01 Javascript
JS基于封装函数实现的表格分页完整示例
2018/06/26 Javascript
vue项目中添加单元测试的方法
2018/07/21 Javascript
Vue-Router的使用方法
2018/09/05 Javascript
Vue中的作用域CSS和CSS模块的区别
2018/10/09 Javascript
vue中使用v-for时为什么不能用index作为key
2020/04/04 Javascript
Python虚拟环境Virtualenv使用教程
2015/05/18 Python
Python反射用法实例简析
2017/12/22 Python
python+opencv+caffe+摄像头做目标检测的实例代码
2018/08/03 Python
Python遍历文件夹 处理json文件的方法
2019/01/22 Python
Python3.5装饰器典型案例分析
2019/04/30 Python
python关于矩阵重复赋值覆盖问题的解决方法
2019/07/19 Python
Python如何把多个PDF文件合并代码实例
2020/02/13 Python
python 贪心算法的实现
2020/09/18 Python
用Python实现职工信息管理系统
2020/12/30 Python
conda安装tensorflow和conda常用命令小结
2021/02/20 Python
html5适合移动应用开发的12大特性
2014/03/19 HTML / CSS
HTML5实现动画效果的方式汇总
2016/02/29 HTML / CSS
澳大利亚票务和娱乐市场领导者:Ticketmaster
2017/03/03 全球购物
Currentbody美国/加拿大:美容仪专家
2020/03/09 全球购物
高三英语教学反思
2014/01/13 职场文书
药店主任岗位责任制
2014/02/10 职场文书
经贸日语专业个人求职信范文
2014/04/29 职场文书
工商行政处罚决定书
2015/06/24 职场文书