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 相关文章推荐
javascript 主动派发事件总结
Aug 09 Javascript
前台js调用后台方法示例
Dec 02 Javascript
jquery浏览器滚动加载技术实现方案
Jun 03 Javascript
node.js+express制作网页计算器
Jan 17 Javascript
JS简单设置下拉选择框默认值的方法
Aug 20 Javascript
Angular 4依赖注入学习教程之简介(一)
Jun 04 Javascript
基于 Vue.js 2.0 酷炫自适应背景视频登录页面实现方式
Jan 17 Javascript
新年快乐! javascript实现超级炫酷的3D烟花特效
Jan 30 Javascript
JavaScript的级联函数用法简单示例【链式调用】
Mar 26 Javascript
JavaScript实现轮播图特效
Apr 10 Javascript
微信小程序实现签到弹窗动画
Sep 21 Javascript
Vue仿Bibibili首页的问题
Jan 21 Vue.js
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
拼音码表的生成
2006/10/09 PHP
php5.3 不支持 session_register() 此函数已启用的解决方法
2013/11/12 PHP
PHP7创建COOKIE和销毁COOKIE的实例方法
2020/02/03 PHP
JMenuTab简单使用说明
2008/03/13 Javascript
JavaScript 快捷键设置实现代码
2009/03/13 Javascript
谈谈关于JavaScript 中的 MVC 模式
2013/04/11 Javascript
js编写trim()函数及正则表达式的运用
2013/10/24 Javascript
jquery加载图片时以淡入方式显示的方法
2015/01/14 Javascript
node.js [superAgent] 请求使用示例
2015/03/13 Javascript
在javascript中随机数 math random如何生成指定范围数值的随机数
2015/10/21 Javascript
实例讲解使用原生JavaScript处理AJAX请求的方法
2016/05/10 Javascript
JavaScript 数组some()和filter()的用法及区别
2016/05/20 Javascript
javascript 动态样式添加的简单实现
2016/10/11 Javascript
完美解决IE不支持Data.parse()的问题
2016/11/24 Javascript
node.js中express中间件body-parser的介绍与用法详解
2017/05/23 Javascript
zTree jQuery 树插件的使用(实例讲解)
2017/09/25 jQuery
Angular浏览器插件Batarang介绍及使用
2018/02/07 Javascript
微信小程序开发背景图显示功能
2018/08/08 Javascript
Handtrack.js库实现实时监测手部运动(推荐)
2021/02/08 Javascript
wxpython 最小化到托盘与欢迎图片的实现方法
2014/06/09 Python
对django中foreignkey的简单使用详解
2019/07/28 Python
python实现网站用户名密码自动登录功能
2019/08/09 Python
基于python全局设置id 自动化测试元素定位过程解析
2019/09/04 Python
python获取依赖包和安装依赖包教程
2020/02/13 Python
Python3 ID3决策树判断申请贷款是否成功的实现代码
2020/05/21 Python
10行Python代码实现Web自动化管控的示例代码
2020/08/14 Python
纯CSS3实现圆圈动态发光特效动画的示例代码
2021/03/08 HTML / CSS
松本清官方海外旗舰店:日本最大的药妆连锁店
2017/11/21 全球购物
GAP阿联酋官网:GAP UAE
2017/11/30 全球购物
Carter’s OshKosh加拿大:购买婴幼儿服装和童装
2018/11/27 全球购物
如何进行Linux分区优化
2016/09/13 面试题
资产评估专业大学生求职信
2013/09/29 职场文书
大气污染防治方案
2014/05/19 职场文书
领导批评与自我批评范文
2014/10/16 职场文书
党的群众路线教育实践活动整改方案
2014/10/28 职场文书
Mybatis 一级缓存和二级缓存原理区别
2022/09/23 Java/Android