ES6(promise)_解决回调地狱初体验
一、前言
通过这个例子对promise解决回调地狱问题有一个初步理解。
二、主要内容
1、回调地狱:如下图所示,一个回调函数里面嵌套一个回调函数,这样的代码可读性较低也比较恶心
2、下面用一个简单的例子来体验回调
举例:我们想要按照顺序读取三个文件,a.txt b.txt c.txt 通过已经学的知识,发现下面的代码是不行的(代码是在node环境中实现)
(1)项目目录结构如下:
(2)callback.js: 如下
- var fs = require('fs');
- //读取文件a.txt
- fs.readFile('./data/a.txt', function (err, data) {
- if (err) {
- throw err
- }
- console.log(data.toString());
- })
- //读取文件b.txt
- fs.readFile('./data/b.txt', function (err, data) {
- if (err) {
- throw err
- }
- console.log(data.toString());
- })
- //读取文件c.txt
- fs.readFile('./data/c.txt', function (err, data) {
- if (err) {
- throw err
- }
- console.log(data.toString());
- })
(3)测试:发现读取文件的顺序并不是先a.txt --> b.txt -->c.txt,因为这里读取文件是异步的,这里执行的顺序取决于文件的大小
(4)为了让读取的文件按照顺序来,我们可以用一下嵌套的方式 ,这种方式可以保证读取的顺序是按照a b c顺序来的,,但是代码嵌套得比较恶心,,这里只有三层嵌套,
- var fs = require('fs');
- //读取a.txt
- fs.readFile('./data/a.txt', function (err, data) {
- if (err) {
- throw err
- }
- console.log(data.toString());
- //读取b.txt
- fs.readFile('./data/b.txt', function (err, data) {
- if (err) {
- throw err
- }
- console.log(data.toString());
- //读取c.txt
- fs.readFile('./data/c.txt', function (err, data) {
- if (err) {
- throw err
- }
- console.log(data.toString());
- })
- })
- })
3、使用promise来解决回调嵌套(不了解promise的可以参照阮一峰老师的es6文档)
- var fs = require('fs')
//创建p1的promise容器- var p1 = new Promise(function (resolve, reject) {
- fs.readFile('./data/a.txt', 'utf8', function (err, data) {
- if (err) {
- reject(err)
- } else {
- resolve(data)
- }
- })
- })
//创建p2的promise容器- var p2 = new Promise(function (resolve, reject) {
- fs.readFile('./data/b.txt', 'utf8', function (err, data) {
- if (err) {
- reject(err)
- } else {
- resolve(data)
- }
- })
- })
//创建p3的promise容器- var p3 = new Promise(function (resolve, reject) {
- fs.readFile('./data/c.txt', 'utf8', function (err, data) {
- if (err) {
- reject(err)
- } else {
- resolve(data)
- }
- })
- })
- p1
- .then(function (data) {
- console.log(data)
- // 当 p1 读取成功的时候
- // 当前函数中 return 的结果就可以在后面的 then 中 function 接收到
- // 当你 return 123 后面就接收到 123
- // return 'hello' 后面就接收到 'hello'
- // 没有 return 后面收到的就是 undefined
- // 真正有用的是:我们可以 return 一个 Promise 对象
- // 当 return 一个 Promise 对象的时候,后续的 then 中的 方法的第一个参数会作为 p2 的 resolve
- //
- return p2
- }, function (err) {
- console.log('读取文件失败了', err)
- })
- .then(function (data) {
- console.log(data)
- return p3
- })
- .then(function (data) {
- console.log(data)
- console.log('end')
- })
为什么可以那样做:
4、将上面的方法封装
- var fs = require('fs')
- function pReadFile(filePath) {
- return new Promise(function (resolve, reject) {
- fs.readFile(filePath, 'utf8', function (err, data) {
- if (err) {
- reject(err)
- } else {
- resolve(data)
- }
- })
- })
- }
- pReadFile('./data/a.txt')
- .then(function (data) {
- console.log(data)
- return pReadFile('./data/b.txt')
- })
- .then(function (data) {
- console.log(data)
- return pReadFile('./data/c.txt')
- })
- .then(function (data) {
- console.log(data)
- })
三、总结
参考:阮一峰:http://es6.ruanyifeng.com
ES6(promise)_解决回调地狱初体验的更多相关文章
- ES6(promise)_解决回调嵌套简单应用
一.前言 这个小案例是在node平台上应用的所以需要保证你的电脑: 1.安装和配置node.js环境 2.需要用node.js来开启一个http-server: 开启方法:https://blog.c ...
- promise对象解决回调地狱
先放一张图片感受一下回调地狱 看起来是真的很让人头痛的东西 而现在我这里使用promise对象来解决回调地狱 采用链式的 then,可以指定一组按照次序调用的回调函数. 这时,前一个 then 里的一 ...
- 使用ES6的Promise完美解决回调地狱
相信经常使用ajax的前端小伙伴,都会遇到这样的困境:一个接口的参数会需要使用另一个接口获取. 年轻的前端可能会用同步去解决(笑~),因为我也这么干过,但是极度影响性能和用户体验. 正常的前端会把接口 ...
- 【JavaScript】 使用Async 和 Promise 完美解决回调地狱
很久以前就学习过Async和Promise,但总是一知半解的. 今天在写NodeJS的时候,发现好多第三方库使用回调,这样在实际操作中会出现多重回调,这就是传说中的JS回调地狱. 举个例子 有一个方法 ...
- Promise如何解决回调地狱
为什么要有promise:解决(回调地狱)的问题 ### 回调地狱: ```js //跟以前的if条件地狱很像 // if(){ // if(){ // if(){ // } // } //} $.g ...
- 回调地狱以及用promise怎么解决回调地狱
哈哈哈,我又又又回来了,不好意思,最近枸杞喝的比较到位,精力比较旺盛. 现在我们来聊一聊啥是回调地狱,注意是回调地狱啊 不是RB人民最爱拍的那啥地狱啊,来吧,上车吧少年,这是去幼儿园的车 都让开, ...
- 基于PROMISE解决回调地狱问题
回调地狱问题: 在使用JavaScript时,为了实现某些逻辑经常会写出层层嵌套的回调函数,如果嵌套过多,会极大影响代码可读性和逻辑,这种情况也被成为回调地狱.比如说你要把一个函数 A 作为回调函数, ...
- Promise,async/await解决回调地狱
先说一下async的用法,它作为一个关键字放到函数前面,用于表示函数是一个异步函数,因为async就是异步的意思, 异步函数也就意味着该函数的执行不会阻塞后面代码的执行. 写一个async 函数 as ...
- async + promise 解决回调地狱
// 解决异步回调地狱的方案: async + promise async function writeFile() { // 打开文件 const fd = await new Promis ...
随机推荐
- [开源 .NET 跨平台 Crawler 数据采集 爬虫框架: DotnetSpider] [一] 初衷与架构设计
[DotnetSpider 系列目录] 一.初衷与架构设计 二.基本使用 三.配置式爬虫 四.JSON数据解析与配置系统 五.如何做全站采集 为什么要造轮子 同学们可以去各大招聘网站查看一下爬虫工程师 ...
- CF980E
题面 Panel 国将举办名为数字游戏的年度表演.每个省派出一名选手. 国家有 n 个编号从 1 到 n 的省,每个省刚好有一条路径将其与其他省相连.第 i 个省出来的代表有 2^i 名粉丝. 今年, ...
- Nginx 模块分类
L:34
- Apache与Nginx动静分离
概述 Nginx的静态处理能力很强,但是动态处理能力不足,因此,在企业中常用动静分离技术.动静分离技术其实是采用代理的方式,在server{}段中加入带正则匹配的location来指定匹配项 针对PH ...
- [BZOJ 1968] [AHOI 2005] 约数研究
Description Input 只有一行一个整数 \(N\). Output 只有一行输出,为整数 \(M\),即 \(f(1)\) 到 \(f(N)\) 的累加和. Sample Input 3 ...
- BZOJ3638[Codeforces280D]k-Maximum Subsequence Sum&BZOJ3272Zgg吃东西&BZOJ3267KC采花——模拟费用流+线段树
题目描述 给一列数,要求支持操作: 1.修改某个数的值 2.读入l,r,k,询问在[l,r]内选不相交的不超过k个子段,最大的和是多少. 输入 The first line contains inte ...
- PHP——生成唯一序列号UUID
<?php function uuid($uid = '') { $chars = md5(uniqid(mt_rand(), true)); $uuid = substr($chars, 0, ...
- SPOJ QTREE-Query on a tree-树链剖分-边权
用每个点代表父节点到此点的边.建立一一映射后就可以用点权的方法处理了. 注意的是路径两端节点的处理 #include <cstdio> #include <algorithm> ...
- 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 由唯一分解 ...
- Ikki's Story IV - Panda's Trick POJ - 3207(水2 - sat 在圈内 还是 在圈外)
题意: 就是一个圈上有n个点,给出m对个点,这m对个点,每一对都有一条边,合理安排这些边在圈内或圈外,能否不相交 解析: 我手残 我手残 我手残 写一下情况 只能是一个在圈外 一个在圈内 即一个1一个 ...