一、前言

通过这个例子对promise解决回调地狱问题有一个初步理解。

二、主要内容

1、回调地狱:如下图所示,一个回调函数里面嵌套一个回调函数,这样的代码可读性较低也比较恶心

2、下面用一个简单的例子来体验回调

      举例:我们想要按照顺序读取三个文件,a.txt  b.txt  c.txt  通过已经学的知识,发现下面的代码是不行的(代码是在node环境中实现)

(1)项目目录结构如下:

(2)callback.js: 如下

  1. var fs = require('fs');
  2. //读取文件a.txt
  3. fs.readFile('./data/a.txt', function (err, data) {
  4. if (err) {
  5. throw err
  6. }
  7.  
  8. console.log(data.toString());
  9. })
  10.  
  11. //读取文件b.txt
  12. fs.readFile('./data/b.txt', function (err, data) {
  13. if (err) {
  14. throw err
  15. }
  16.  
  17. console.log(data.toString());
  18. })
  19.  
  20. //读取文件c.txt
  21. fs.readFile('./data/c.txt', function (err, data) {
  22. if (err) {
  23. throw err
  24. }
  25.  
  26. console.log(data.toString());
  27. })

(3)测试:发现读取文件的顺序并不是先a.txt --> b.txt -->c.txt,因为这里读取文件是异步的,这里执行的顺序取决于文件的大小

(4)为了让读取的文件按照顺序来,我们可以用一下嵌套的方式 ,这种方式可以保证读取的顺序是按照a b c顺序来的,,但是代码嵌套得比较恶心,,这里只有三层嵌套,

  1. var fs = require('fs');
  2. //读取a.txt
  3. fs.readFile('./data/a.txt', function (err, data) {
  4. if (err) {
  5. throw err
  6. }
  7.  
  8. console.log(data.toString());
  9. //读取b.txt
  10. fs.readFile('./data/b.txt', function (err, data) {
  11. if (err) {
  12. throw err
  13. }
  14.  
  15. console.log(data.toString());
  16. //读取c.txt
  17. fs.readFile('./data/c.txt', function (err, data) {
  18. if (err) {
  19. throw err
  20. }
  21.  
  22. console.log(data.toString());
  23. })
  24.  
  25. })
  26. })

 3、使用promise来解决回调嵌套(不了解promise的可以参照阮一峰老师的es6文档)

  1. var fs = require('fs')

  2. //创建p1的promise容器
  3. var p1 = new Promise(function (resolve, reject) {
  4. fs.readFile('./data/a.txt', 'utf8', function (err, data) {
  5. if (err) {
  6. reject(err)
  7. } else {
  8. resolve(data)
  9. }
  10. })
  11. })

  12. //创建p2的promise容器
  13. var p2 = new Promise(function (resolve, reject) {
  14. fs.readFile('./data/b.txt', 'utf8', function (err, data) {
  15. if (err) {
  16. reject(err)
  17. } else {
  18. resolve(data)
  19. }
  20. })
  21. })

  22. //创建p3的promise容器
  23. var p3 = new Promise(function (resolve, reject) {
  24. fs.readFile('./data/c.txt', 'utf8', function (err, data) {
  25. if (err) {
  26. reject(err)
  27. } else {
  28. resolve(data)
  29. }
  30. })
  31. })

  32. p1
  33. .then(function (data) {
  34. console.log(data)
  35. // 当 p1 读取成功的时候
  36. // 当前函数中 return 的结果就可以在后面的 then 中 function 接收到
  37. // 当你 return 123 后面就接收到 123
  38. // return 'hello' 后面就接收到 'hello'
  39. // 没有 return 后面收到的就是 undefined
  40. // 真正有用的是:我们可以 return 一个 Promise 对象
  41. // 当 return 一个 Promise 对象的时候,后续的 then 中的 方法的第一个参数会作为 p2 的 resolve
  42. //
  43. return p2
  44. }, function (err) {
  45. console.log('读取文件失败了', err)
  46. })
  47. .then(function (data) {
  48. console.log(data)
  49. return p3
  50. })
  51. .then(function (data) {
  52. console.log(data)
  53. console.log('end')
  54. })

为什么可以那样做:

 4、将上面的方法封装

  1. var fs = require('fs')
  2.  
  3. function pReadFile(filePath) {
  4. return new Promise(function (resolve, reject) {
  5. fs.readFile(filePath, 'utf8', function (err, data) {
  6. if (err) {
  7. reject(err)
  8. } else {
  9. resolve(data)
  10. }
  11. })
  12. })
  13. }
  14.  
  15. pReadFile('./data/a.txt')
  16. .then(function (data) {
  17. console.log(data)
  18. return pReadFile('./data/b.txt')
  19. })
  20. .then(function (data) {
  21. console.log(data)
  22. return pReadFile('./data/c.txt')
  23. })
  24. .then(function (data) {
  25. console.log(data)
  26. })

三、总结

参考:阮一峰:http://es6.ruanyifeng.com

ES6(promise)_解决回调地狱初体验的更多相关文章

  1. ES6(promise)_解决回调嵌套简单应用

    一.前言 这个小案例是在node平台上应用的所以需要保证你的电脑: 1.安装和配置node.js环境 2.需要用node.js来开启一个http-server: 开启方法:https://blog.c ...

  2. promise对象解决回调地狱

    先放一张图片感受一下回调地狱 看起来是真的很让人头痛的东西 而现在我这里使用promise对象来解决回调地狱 采用链式的 then,可以指定一组按照次序调用的回调函数. 这时,前一个 then 里的一 ...

  3. 使用ES6的Promise完美解决回调地狱

    相信经常使用ajax的前端小伙伴,都会遇到这样的困境:一个接口的参数会需要使用另一个接口获取. 年轻的前端可能会用同步去解决(笑~),因为我也这么干过,但是极度影响性能和用户体验. 正常的前端会把接口 ...

  4. 【JavaScript】 使用Async 和 Promise 完美解决回调地狱

    很久以前就学习过Async和Promise,但总是一知半解的. 今天在写NodeJS的时候,发现好多第三方库使用回调,这样在实际操作中会出现多重回调,这就是传说中的JS回调地狱. 举个例子 有一个方法 ...

  5. Promise如何解决回调地狱

    为什么要有promise:解决(回调地狱)的问题 ### 回调地狱: ```js //跟以前的if条件地狱很像 // if(){ // if(){ // if(){ // } // } //} $.g ...

  6. 回调地狱以及用promise怎么解决回调地狱

    哈哈哈,我又又又回来了,不好意思,最近枸杞喝的比较到位,精力比较旺盛. 现在我们来聊一聊啥是回调地狱,注意是回调地狱啊   不是RB人民最爱拍的那啥地狱啊,来吧,上车吧少年,这是去幼儿园的车 都让开, ...

  7. 基于PROMISE解决回调地狱问题

    回调地狱问题: 在使用JavaScript时,为了实现某些逻辑经常会写出层层嵌套的回调函数,如果嵌套过多,会极大影响代码可读性和逻辑,这种情况也被成为回调地狱.比如说你要把一个函数 A 作为回调函数, ...

  8. Promise,async/await解决回调地狱

    先说一下async的用法,它作为一个关键字放到函数前面,用于表示函数是一个异步函数,因为async就是异步的意思, 异步函数也就意味着该函数的执行不会阻塞后面代码的执行. 写一个async 函数 as ...

  9. async + promise 解决回调地狱

    // 解决异步回调地狱的方案: async + promise async function writeFile() {   // 打开文件   const fd = await new Promis ...

随机推荐

  1. [开源 .NET 跨平台 Crawler 数据采集 爬虫框架: DotnetSpider] [一] 初衷与架构设计

    [DotnetSpider 系列目录] 一.初衷与架构设计 二.基本使用 三.配置式爬虫 四.JSON数据解析与配置系统 五.如何做全站采集 为什么要造轮子 同学们可以去各大招聘网站查看一下爬虫工程师 ...

  2. CF980E

    题面 Panel 国将举办名为数字游戏的年度表演.每个省派出一名选手. 国家有 n 个编号从 1 到 n 的省,每个省刚好有一条路径将其与其他省相连.第 i 个省出来的代表有 2^i 名粉丝. 今年, ...

  3. Nginx 模块分类

    L:34

  4. Apache与Nginx动静分离

    概述 Nginx的静态处理能力很强,但是动态处理能力不足,因此,在企业中常用动静分离技术.动静分离技术其实是采用代理的方式,在server{}段中加入带正则匹配的location来指定匹配项 针对PH ...

  5. [BZOJ 1968] [AHOI 2005] 约数研究

    Description Input 只有一行一个整数 \(N\). Output 只有一行输出,为整数 \(M\),即 \(f(1)\) 到 \(f(N)\) 的累加和. Sample Input 3 ...

  6. BZOJ3638[Codeforces280D]k-Maximum Subsequence Sum&BZOJ3272Zgg吃东西&BZOJ3267KC采花——模拟费用流+线段树

    题目描述 给一列数,要求支持操作: 1.修改某个数的值 2.读入l,r,k,询问在[l,r]内选不相交的不超过k个子段,最大的和是多少. 输入 The first line contains inte ...

  7. PHP——生成唯一序列号UUID

    <?php function uuid($uid = '') { $chars = md5(uniqid(mt_rand(), true)); $uuid = substr($chars, 0, ...

  8. SPOJ QTREE-Query on a tree-树链剖分-边权

    用每个点代表父节点到此点的边.建立一一映射后就可以用点权的方法处理了. 注意的是路径两端节点的处理 #include <cstdio> #include <algorithm> ...

  9. Codeforces Round #518 (Div. 2) B. LCM gcd+唯一分解定律

    题意:给出b 求lcm(a,b)/a 在b从1-1e18有多少个不同得结果 思路lcm*gcd=a*b  转换成    b/gcd(a,b) 也就是看gcd(a,b)有多少个值  可以把b 由唯一分解 ...

  10. Ikki's Story IV - Panda's Trick POJ - 3207(水2 - sat 在圈内 还是 在圈外)

    题意: 就是一个圈上有n个点,给出m对个点,这m对个点,每一对都有一条边,合理安排这些边在圈内或圈外,能否不相交 解析: 我手残 我手残 我手残 写一下情况 只能是一个在圈外 一个在圈内 即一个1一个 ...