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系列之数据类型 字符串
Jun 08 Javascript
jQuery 过滤not()与filter()实例代码
May 10 Javascript
AngularJS中处理多个promise的方式
Feb 02 Javascript
AngularJs基本特性解析(一)
Jul 21 Javascript
ionic App问题总结系列之ionic点击系统返回键退出App
Aug 19 Javascript
十分钟带你快速了解React16新特性
Nov 10 Javascript
JS常见构造模式实例对比分析
Aug 27 Javascript
简单了解JavaScript中常见的反模式
Jun 21 Javascript
Angular之jwt令牌身份验证的实现
Feb 14 Javascript
浅谈vue项目利用Hbuilder打包成APP流程,以及遇到的坑
Sep 12 Javascript
echarts浮动显示单位的实现方法示例
Dec 04 Javascript
详解Vue的sync修饰符
May 15 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
LotusPhp笔记之:Logger组件的使用方法
2013/05/06 PHP
codeigniter中view通过循环显示数组数据的方法
2015/03/20 PHP
PHP SPL标准库之SplFixedArray使用实例
2015/05/12 PHP
Thinkphp 框架配置操作之动态配置、扩展配置及批量配置实例分析
2020/05/15 PHP
js树形控件脚本代码
2008/07/24 Javascript
Mootools 1.2教程 事件处理
2009/09/15 Javascript
Javascript document.referrer判断访客来源网址
2020/05/15 Javascript
js word表格动态添加代码
2010/06/07 Javascript
灵活应用js调试技巧解决样式问题的步骤分享
2012/03/15 Javascript
一个简单的Ext.XTemplate的实例代码
2012/03/18 Javascript
ExtJS[Desktop]实现图标换行示例代码
2013/11/17 Javascript
tangram框架响应式加载图片方法
2013/11/21 Javascript
DOM节点删除函数removeChild()用法实例
2015/01/12 Javascript
js+HTML5实现canvas多种颜色渐变效果的方法
2015/06/05 Javascript
BootStrap 智能表单实战系列(十)自动完成组件的支持
2016/06/13 Javascript
BootStrap智能表单实战系列(十一)级联下拉的支持
2016/06/13 Javascript
js中怎么判断两个字符串相等的实例
2019/01/17 Javascript
详解nvm管理多版本node踩坑
2019/07/26 Javascript
[02:26]DOTA2英雄米拉娜基础教程
2013/11/25 DOTA
[02:12]探秘2016国际邀请赛中国区预选赛选手房间
2016/06/25 DOTA
在Python中用split()方法分割字符串的使用介绍
2015/05/20 Python
python操作oracle的完整教程分享
2018/01/30 Python
使用Python检测文章抄袭及去重算法原理解析
2019/06/14 Python
TensorFlow实现简单的CNN的方法
2019/07/18 Python
Python的垃圾回收机制详解
2019/08/28 Python
python数据化运营的重要意义
2019/11/25 Python
pytorch 实现tensor与numpy数组转换
2019/12/27 Python
使用python批量转换文件编码为UTF-8的实现
2020/04/03 Python
小女主人连衣裙:Little Mistress
2017/07/10 全球购物
受希腊女神灵感的晚礼服、鸡尾酒礼服和婚纱:THEIA
2018/04/15 全球购物
C++如何引用一个已经定义过的全局变量
2014/08/25 面试题
求职信范文大全
2014/05/26 职场文书
学校综治宣传月活动总结
2014/07/02 职场文书
个人年度总结报告
2015/03/09 职场文书
留学文书中的个人陈述,应该注意哪些问题?
2019/08/23 职场文书
面试中canvas绘制图片模糊图片问题处理
2022/03/13 Javascript