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多线程的实现方法
May 08 Javascript
基于mootools 1.3框架下的图片滑动效果代码
Apr 22 Javascript
js自定义事件及事件交互原理概述(一)
Feb 01 Javascript
浅析XMLHttpRequest的缓存问题
Dec 13 Javascript
百度地图JavascriptApi Marker平滑移动及车头指向行径方向
Mar 13 Javascript
javascript基本数据类型和转换
Mar 17 Javascript
JQuery常见节点操作实例分析
May 15 jQuery
vue实现条件叠加搜索的解决方法
May 28 Javascript
微信小程序 调用远程接口 给全局数组赋值代码实例
Aug 13 Javascript
vue vantUI tab切换时 list组件不触发load事件的问题及解决方法
Feb 14 Javascript
vue+render+jsx实现可编辑动态多级表头table的实例代码
Apr 01 Javascript
Postman无法正常返回结果问题解决
Aug 28 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
WHOOPS PHP调试库的使用
2017/09/29 PHP
浅析PHP中的闭包和匿名函数
2017/12/25 PHP
PHP实现动态添加XML中数据的方法
2018/03/30 PHP
用一段js程序来实现动画功能
2007/03/06 Javascript
DIY jquery plugin - tabs标签切换实现代码
2010/12/11 Javascript
JQuery一种取同级值的方式(比如你在GridView中)
2012/03/15 Javascript
js实现点小图看大图效果的思路及示例代码
2013/10/28 Javascript
Javascript中浮点数相乘的一个解决方法
2014/06/03 Javascript
Nodejs Post请求报socket hang up错误的解决办法
2014/09/25 NodeJs
JavaScript中自定义事件用法分析
2014/12/23 Javascript
简述jQuery ajax的执行顺序
2016/01/05 Javascript
微信小程序 底部导航栏目开发资料
2016/12/05 Javascript
微信小程序 scroll-view组件实现列表页实例代码
2016/12/14 Javascript
微信小程序 MD5加密登录密码详解及实例代码
2017/01/12 Javascript
利用PM2部署node.js项目的方法教程
2017/05/10 Javascript
cropper js基于vue的图片裁剪上传功能的实现代码
2018/03/01 Javascript
webpack-mvc 传统多页面组件化开发详解
2019/05/07 Javascript
Vue 使用typescript如何优雅的调用swagger API
2020/09/01 Javascript
js重写alert事件(避免alert弹框标题出现网址)
2020/12/04 Javascript
Python中声明只包含一个元素的元组数据方法
2014/08/25 Python
Python使用Paramiko模块编写脚本进行远程服务器操作
2016/05/05 Python
Python中关键字nonlocal和global的声明与解析
2017/03/12 Python
python简单贪吃蛇开发
2019/01/28 Python
Django Rest framework三种分页方式详解
2019/07/26 Python
Python基础之高级变量类型实例详解
2020/01/03 Python
pytorch之ImageFolder使用详解
2020/01/06 Python
Python项目实战之使用Django框架实现支付宝付款功能
2021/02/23 Python
稀有和绝版书籍:Biblio.com
2017/02/02 全球购物
高级工程师岗位职责
2013/12/15 职场文书
新年团拜会主持词
2014/04/02 职场文书
对外汉语专业大学生职业生涯规划范文
2014/09/13 职场文书
教师国庆节演讲稿范文2014
2014/09/21 职场文书
JS不要再到处使用绝对等于运算符了
2021/04/30 Javascript
React实现动效弹窗组件
2021/06/21 Javascript
Java循环队列与非循环队列的区别总结
2021/06/22 Java/Android
在NumPy中深拷贝和浅拷贝相关操作的定义和背后的原理
2022/04/14 Python