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类中的公有变量和私有变量
Jul 24 Javascript
基于jQuery的让非HTML5浏览器支持placeholder属性的代码
May 24 Javascript
用JQuery模仿淘宝的图片放大镜显示效果
Sep 15 Javascript
使用JavaScript实现Java的List功能(实例讲解)
Nov 07 Javascript
Jquery uploadify图片上传插件无法上传的解决方法
Dec 16 Javascript
js中数组(Array)的排序(sort)注意事项说明
Jan 24 Javascript
javascript异步编程的4种方法
Feb 19 Javascript
JS实现标签滚动切换效果
Dec 25 Javascript
在vue中使用v-bind:class的选项卡方法
Sep 27 Javascript
微信小程序实现录音时的麦克风动画效果实例
May 18 Javascript
javascript面向对象三大特征之封装实例详解
Jul 24 Javascript
JavaScript实现无限轮播效果
Nov 19 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
THINKPHP2.0到3.0有哪些改进之处
2015/01/04 PHP
php创建session的方法实例详解
2015/01/27 PHP
php使用Jpgraph绘制复杂X-Y坐标图的方法
2015/06/10 PHP
两种php去除二维数组的重复项方法
2015/11/04 PHP
详解WordPress中给链接添加查询字符串的方法
2015/12/18 PHP
PHP实现图的邻接矩阵表示及几种简单遍历算法分析
2017/11/24 PHP
JavaScript实现禁止后退的方法
2006/12/27 Javascript
java script编程起步(第三课)
2007/01/10 Javascript
在浏览器窗口上添加遮罩层的方法
2012/11/12 Javascript
热点新闻滚动特效的js代码
2013/08/17 Javascript
Javscript删除数组中指定元素并返回新数组
2014/03/06 Javascript
Javascript Memoizer浅析
2014/10/16 Javascript
使用Javascript监控前端相关数据的代码
2016/10/27 Javascript
原生JS实现圆环拖拽效果
2017/04/07 Javascript
webpack vue项目开发环境局域网访问方法
2018/03/20 Javascript
关于vuejs中v-if和v-show的区别及v-show不起作用问题
2018/03/26 Javascript
vue移动端路由切换实例分析
2018/05/14 Javascript
vue实现底部菜单功能
2018/07/24 Javascript
用POSTMAN发送JSON格式的POST请求示例
2018/09/04 Javascript
vue中使用带隐藏文本信息的图片、图片水印的方法
2020/04/24 Javascript
python处理csv数据动态显示曲线实例代码
2018/01/23 Python
Python比较2个时间大小的实现方法
2018/04/10 Python
python安装pywin32clipboard的操作方法
2019/01/24 Python
Python中@property的理解和使用示例
2019/06/11 Python
python使用opencv对图像mask处理的方法
2019/07/05 Python
Python 函数绘图及函数图像微分与积分
2019/11/20 Python
pytorch 查看cuda 版本方式
2020/06/23 Python
HTML5头部标签的一些常用信息小结
2016/10/23 HTML / CSS
惠普美国官方商店:HP Official Store
2016/08/28 全球购物
ALDO加拿大官网:加拿大女鞋品牌
2018/12/22 全球购物
cf战队收人广告词
2014/03/14 职场文书
纪念九一八爱国演讲稿600字
2014/09/14 职场文书
我的暑假生活作文(五年级)范文
2019/08/07 职场文书
《学会生存》读后感3篇
2019/12/09 职场文书
JavaScript数组 几个常用方法总结
2021/11/11 Javascript
星际争霸:毕姥爷vs解冻01
2022/04/01 星际争霸