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 本页面传值实现代码
May 17 Javascript
JavaScript高级程序设计 扩展--关于动态原型
Nov 09 Javascript
解析prototype,JQuery中跳出each循环的方法
Dec 12 Javascript
JavaScript中的ajax功能的概念和示例详解
Oct 17 Javascript
基于JavaScript实现的插入排序算法分析
Apr 14 Javascript
解决JSON.stringify()自动将中文转译成unicode的问题
Jan 05 Javascript
angular中如何绑定iframe中src的方法
Feb 01 Javascript
小程序云开发之用户注册登录
May 18 Javascript
简单了解JavaScript异步
May 23 Javascript
vue使用代理解决请求跨域问题详解
Jul 24 Javascript
el-table表头根据内容自适应完美解决表头错位和固定列错位
Jan 07 Javascript
js动态添加带圆圈序号列表的实例代码
Feb 18 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
咖啡豆分级制度 咖啡豆等级分类 咖啡豆是按口感分类的吗?
2021/03/05 新手入门
php array_merge下进行数组合并的代码
2008/07/22 PHP
PHP cron中的批处理
2008/09/16 PHP
php过滤html标记属性类用法实例
2014/09/23 PHP
php把数组值转换成键的方法
2015/07/13 PHP
在WordPress的后台中添加顶级菜单和子菜单的函数详解
2016/01/11 PHP
CodeIgniter开发实现支付宝接口调用的方法示例
2016/11/14 PHP
laravel通用化的CURD的实现
2019/12/13 PHP
laravel邮件发送的实现代码示例
2020/01/31 PHP
jQuery动画与特效详解
2015/02/01 Javascript
jquery Ajax 全局调用封装实例详解
2017/01/16 Javascript
JavaScript数据结构之链表的实现
2017/03/19 Javascript
vue中element组件样式修改无效的解决方法
2018/02/03 Javascript
用element的upload组件实现多图片上传和压缩的示例代码
2019/02/12 Javascript
el-input 标签中密码的显示和隐藏功能的实例代码
2019/07/19 Javascript
js前端如何写一个精确的倒计时代码
2019/10/25 Javascript
深入理解 TypeScript Reflect Metadata
2019/12/12 Javascript
js实现计时器秒表功能
2019/12/16 Javascript
[01:03:41]DOTA2-DPC中国联赛 正赛 Dynasty vs XG BO3 第三场 2月2日
2021/03/11 DOTA
python3实现抓取网页资源的 N 种方法
2017/05/02 Python
windows下Virtualenvwrapper安装教程
2017/12/13 Python
使用Tensorflow实现可视化中间层和卷积层
2020/01/24 Python
Python 实现打印单词的菱形字符图案
2020/04/12 Python
HTML5实现可缩放时钟代码
2017/08/28 HTML / CSS
美国最大的宠物用品零售商:PetSmart
2016/11/14 全球购物
加拿大时尚潮流大码女装购物网站:Addition Elle
2018/04/02 全球购物
西班牙最大的婴儿用品网上商店:Bebitus
2019/05/30 全球购物
PHP引擎php.ini参数优化深入讲解
2021/03/24 PHP
活动志愿者自荐信
2014/01/27 职场文书
怎样拟定创业计划书
2014/05/01 职场文书
会计学习心得体会
2014/09/09 职场文书
合伙经营协议书范本
2014/09/13 职场文书
教师群众路线学习心得体会
2014/11/04 职场文书
2014年党风建设工作总结
2014/11/19 职场文书
2015年保险业务员工作总结
2015/05/27 职场文书
设置IIS Express并发数
2022/07/07 Servers