Promise做异步实例
Promise做异步实例
一、总结
一句话总结:
new Promise实例,then方法执行回调,catch抛出异常
function getFileByPath(fpath) { return new Promise(function (resolve, reject) { fs.readFile(fpath, 'utf-8', (err, dataStr) => { if (err) return reject(err) resolve(dataStr) }) }) } // 有时候,我们有这样的需求,个上面的需求刚好相反:如果 后续的Promise 执行,依赖于 前面 Promise 执行的结果,如果前面的失败了,则后面的就没有继续执行下去的意义了,此时,我们想要实现,一旦有报错,则立即终止所有 Promise的执行; getFileByPath('./files/1.txt') .then(function (data) { console.log(data) // 读取文件2 return getFileByPath('./files/22.txt') }) .then(function (data) { console.log(data) return getFileByPath('./files/3.txt') }) .then(function (data) { console.log(data) }) .catch(function (err) { // catch 的作用: 如果前面有任何的 Promise 执行失败,则立即终止所有 promise 的执行,并 马上进入 catch 去处理 Promise中 抛出的异常; console.log('这是自己的处理方式:' + err.message) })
1、回调函数解决异步实例?
通过回调函数接收异步操作的结果,不然正常情况下没有办法接收到异步操作的结果
function getFileByPath(fpath, callback) { fs.readFile(fpath, 'utf-8', (err, dataStr) => { // 如果报错了,进入if分支后,if后面的代码就没有必要执行了 if (err) return callback(err) // console.log(dataStr) // return dataStr callback(null, dataStr) }) } /* var result = getFileByPath(path.join(__dirname, './files/1.txt')) console.log(result) */ getFileByPath(path.join(__dirname, './files/11.txt'), (err, dataStr) => { // console.log(dataStr + '-----') if (err) return console.log(err.message) console.log(dataStr) })
2、为什么回调函数解决异步问题会有回调地狱的问题?
回调地狱是因为要保证异步函数的顺序,比如异步函数先读取文件1,读取文件1成功之后(回调内),又异步函数读取文件2,以此类推,等等
3、Promise函数作用?
Promise解决 回调函数解决异步问题造成的回调地狱问题
4、Promise注意点?
Promise本身是一个构造函数
5、每当 new 一个 Promise 实例的时候,就会立即 执行这个 异步操作中的代码?
new Promise 的时候,除了能够得到 一个 promise 实例之外,还会立即调用 我们为 Promise 构造函数传递的那个 function,执行这个 function 中的 异步操作代码
// 也就是说,new 的时候,除了能够得到 一个 promise 实例之外,还会立即调用 我们为 Promise 构造函数传递的那个 function,执行这个 function 中的 异步操作代码; var promise = new Promise(function () { fs.readFile('./files/2.txt', 'utf-8', (err, dataStr) => { if (err) throw err console.log(dataStr) }) })
6、Promise对象中的resolve和reject怎么来的?
resolve和reject是回调函数,通过then传进去的回调函数,then还是比回调中的异步操作执行的快
7、Promise执行步骤?
先返回promise对象,然后执行then,然后通过then传递resolve和reject,然后执行完异步操作,然后执行resolve或者reject
function getFileByPath(fpath) { return new Promise(function (resolve, reject) { fs.readFile(fpath, 'utf-8', (err, dataStr) => { if (err) return reject(err) resolve(dataStr) }) }) } getFileByPath('./files/2.txt') .then(function (data) { console.log(data + '-------') }, function (err) { console.log(err.message) })
8、如果前面的 Promise 执行失败了,但是,不要影响后续 promise 的正常执行,我们应该怎么做?
我们可以单独为 每个 promise,通过 .then 指定一下失败的回调;
9、promise中catch的作用是什么?
如果前面有任何的 Promise 执行失败,则立即终止所有 promise 的执行,并 马上进入 catch 去处理 Promise中 抛出的异常
function getFileByPath(fpath) { return new Promise(function (resolve, reject) { fs.readFile(fpath, 'utf-8', (err, dataStr) => { if (err) return reject(err) resolve(dataStr) }) }) } // 有时候,我们有这样的需求,个上面的需求刚好相反:如果 后续的Promise 执行,依赖于 前面 Promise 执行的结果,如果前面的失败了,则后面的就没有继续执行下去的意义了,此时,我们想要实现,一旦有报错,则立即终止所有 Promise的执行; getFileByPath('./files/1.txt') .then(function (data) { console.log(data) // 读取文件2 return getFileByPath('./files/22.txt') }) .then(function (data) { console.log(data) return getFileByPath('./files/3.txt') }) .then(function (data) { console.log(data) }) .catch(function (err) { // catch 的作用: 如果前面有任何的 Promise 执行失败,则立即终止所有 promise 的执行,并 马上进入 catch 去处理 Promise中 抛出的异常; console.log('这是自己的处理方式:' + err.message) })
二、Promise做异步实例
博客对应课程的视频位置:
1、封装读取文件的方法
1 // 需求:你要封装一个方法,我给你一个要读取文件的路径,你这个方法能帮我读取文件,并把内容返回给我 2 3 const fs = require('fs') 4 const path = require('path') 5 6 // 这是普通读取文件的方式 7 /* fs.readFile(path.join(__dirname, './files/1.txt'), 'utf-8', (err, dataStr) => { 8 if (err) throw err 9 console.log(dataStr) 10 }) */ 11 12 // 初衷: 给定文件路径,返回读取到的内容 13 // 我们可以规定一下, callback 中,有两个参数,第一个参数,是 失败的结果;第二个参数是成功的结果; 14 // 同时,我们规定了: 如果成功后,返回的结果,应该位于 callback 参数的第二个位置,此时, 第一个位置 由于没有出错,所以,放一个 null; 如果失败了,则 第一个位置放 Error对象,第二个位置防止一个 undefined 15 function getFileByPath(fpath, callback) { 16 fs.readFile(fpath, 'utf-8', (err, dataStr) => { 17 // 如果报错了,进入if分支后,if后面的代码就没有必要执行了 18 if (err) return callback(err) 19 // console.log(dataStr) 20 // return dataStr 21 callback(null, dataStr) 22 }) 23 } 24 25 /* var result = getFileByPath(path.join(__dirname, './files/1.txt')) 26 console.log(result) */ 27 getFileByPath(path.join(__dirname, './files/11.txt'), (err, dataStr) => { 28 // console.log(dataStr + '-----') 29 if (err) return console.log(err.message) 30 console.log(dataStr) 31 })
2、封装读取文件的方法-提高版
1 // 需求:你要封装一个方法,我给你一个要读取文件的路径,你这个方法能帮我读取文件,并把内容返回给我 2 3 const fs = require('fs') 4 const path = require('path') 5 6 7 function getFileByPath(fpath, succCb, errCb) { 8 fs.readFile(fpath, 'utf-8', (err, dataStr) => { 9 if (err) return errCb(err) 10 succCb(dataStr) 11 }) 12 } 13 14 // getFileByPath(path.join(__dirname, './files/11.txt'), function (data) { 15 // console.log(data + '娃哈哈,成功了!!!') 16 // }, function (err) { 17 // console.log('失败的结果,我们使用失败的回调处理了一下:' + err.message) 18 // }) 19 20 // 需求: 先读取文件1,再读取文件2,最后再读取文件3 21 // 回调地狱 22 // 使用 ES6 中的 Promise,来解决 回调地狱的问题; 23 // 问: Promise 的本质是要干什么的:就是单纯的为了解决回调地狱问题;并不能帮我们减少代码量; 24 getFileByPath(path.join(__dirname, './files/1.txt'), function (data) { 25 console.log(data) 26 27 getFileByPath(path.join(__dirname, './files/2.txt'), function (data) { 28 console.log(data) 29 30 getFileByPath(path.join(__dirname, './files/3.txt'), function (data) { 31 console.log(data) 32 }) 33 }) 34 })
3、Promise概念介绍
1 // 1. Promise 是一个 构造函数,既然是构造函数, 那么,我们就可以 new Promise() 得到一个 Promise 的实例; 2 // 2. 在 Promise 上,有两个函数,分别叫做 resolve(成功之后的回调函数) 和 reject(失败之后的回调函数) 3 // 3. 在 Promise 构造函数的 Prototype 属性上,有一个 .then() 方法,也就说,只要是 Promise 构造函数创建的实例,都可以访问到 .then() 方法 4 // 4. Promise 表示一个 异步操作;每当我们 new 一个 Promise 的实例,这个实例,就表示一个具体的异步操作; 5 // 5. 既然 Promise 创建的实例,是一个异步操作,那么,这个 异步操作的结果,只能有两种状态: 6 // 5.1 状态1: 异步执行成功了,需要在内部调用 成功的回调函数 resolve 把结果返回给调用者; 7 // 5.2 状态2: 异步执行失败了,需要在内部调用 失败的回调函数 reject 把结果返回给调用者; 8 // 5.3 由于 Promise 的实例,是一个异步操作,所以,内部拿到 操作的结果后,无法使用 return 把操作的结果返回给调用者; 这时候,只能使用回调函数的形式,来把 成功 或 失败的结果,返回给调用者; 9 // 6. 我们可以在 new 出来的 Promise 实例上,调用 .then() 方法,【预先】 为 这个 Promise 异步操作,指定 成功(resolve) 和 失败(reject) 回调函数; 10 11 12 // 注意:这里 new 出来的 promise, 只是代表 【形式上】的一个异步操作; 13 // 什么是形式上的异步操作:就是说,我们只知道它是一个异步操作,但是做什么具体的异步事情,目前还不清楚 14 // var promise = new Promise() 15 16 17 // 这是一个具体的异步操作,其中,使用 function 指定一个具体的异步操作 18 /* var promise = new Promise(function(){ 19 // 这个 function 内部写的就是具体的异步操作!!! 20 }) */ 21 22 const fs = require('fs') 23 24 // 每当 new 一个 Promise 实例的时候,就会立即 执行这个 异步操作中的代码 25 // 也就是说,new 的时候,除了能够得到 一个 promise 实例之外,还会立即调用 我们为 Promise 构造函数传递的那个 function,执行这个 function 中的 异步操作代码; 26 /* var promise = new Promise(function () { 27 fs.readFile('./files/2.txt', 'utf-8', (err, dataStr) => { 28 if (err) throw err 29 console.log(dataStr) 30 }) 31 }) */ 32 33 34 // 初衷: 给路径,返回读取到的内容 35 function getFileByPath(fpath) { 36 return new Promise(function (resolve, reject) { 37 fs.readFile(fpath, 'utf-8', (err, dataStr) => { 38 39 if (err) return reject(err) 40 resolve(dataStr) 41 42 }) 43 }) 44 } 45 46 /* getFileByPath('./files/2.txt') 47 .then(function (data) { 48 console.log(data + '-------') 49 }, function (err) { 50 console.log(err.message) 51 }) */
4、使用Promise解决回调地狱
1 const fs = require('fs') 2 3 function getFileByPath(fpath) { 4 return new Promise(function (resolve, reject) { 5 fs.readFile(fpath, 'utf-8', (err, dataStr) => { 6 7 if (err) return reject(err) 8 resolve(dataStr) 9 10 }) 11 }) 12 } 13 14 // 先读取文件1,在读取2,最后读取3 15 // 注意: 通过 .then 指定 回调函数的时候,成功的 回调函数,必须传,但是,失败的回调,可以省略不传 16 // 这是一个 错误的示范,千万不要这么用; 硬是把 法拉利,开成了 拖拉机; 17 /* getFileByPath('./files/1.txt') 18 .then(function (data) { 19 console.log(data) 20 21 getFileByPath('./files/2.txt') 22 .then(function (data) { 23 console.log(data) 24 25 getFileByPath('./files/3.txt') 26 .then(function (data) { 27 console.log(data) 28 }) 29 }) 30 }) */ 31 32 // 读取文件1 33 // 在上一个 .then 中,返回一个新的 promise 实例,可以继续用下一个 .then 来处理 34 35 36 // 如果 ,前面的 Promise 执行失败,我们不想让后续的Promise 操作被终止,可以为 每个 promise 指定 失败的回调 37 /* getFileByPath('./files/11.txt') 38 .then(function (data) { 39 console.log(data) 40 41 // 读取文件2 42 return getFileByPath('./files/2.txt') 43 }, function (err) { 44 console.log('这是失败的结果:' + err.message) 45 // return 一个 新的 Promise 46 return getFileByPath('./files/2.txt') 47 }) 48 .then(function (data) { 49 console.log(data) 50 51 return getFileByPath('./files/3.txt') 52 }) 53 .then(function (data) { 54 console.log(data) 55 }).then(function (data) { 56 console.log(data) 57 }) */ 58 59 // console.log('OKOKOK') 60 61 62 63 // 当 我们有这样的需求: 哪怕前面的 Promise 执行失败了,但是,不要影响后续 promise 的正常执行,此时,我们可以单独为 每个 promise,通过 .then 指定一下失败的回调; 64 65 // 有时候,我们有这样的需求,个上面的需求刚好相反:如果 后续的Promise 执行,依赖于 前面 Promise 执行的结果,如果前面的失败了,则后面的就没有继续执行下去的意义了,此时,我们想要实现,一旦有报错,则立即终止所有 Promise的执行; 66 67 getFileByPath('./files/1.txt') 68 .then(function (data) { 69 console.log(data) 70 71 // 读取文件2 72 return getFileByPath('./files/22.txt') 73 }) 74 .then(function (data) { 75 console.log(data) 76 77 return getFileByPath('./files/3.txt') 78 }) 79 .then(function (data) { 80 console.log(data) 81 }) 82 .catch(function (err) { // catch 的作用: 如果前面有任何的 Promise 执行失败,则立即终止所有 promise 的执行,并 马上进入 catch 去处理 Promise中 抛出的异常; 83 console.log('这是自己的处理方式:' + err.message) 84 })
版权申明:欢迎转载,但请注明出处
一些博文中有一些参考内容因时间久远找不到来源了没有注明,如果侵权请联系我删除。
在校每年国奖、每年专业第一,加拿大留学,先后工作于华东师范大学和香港教育大学。
2024-10-30:27岁,宅加太忙,特此在网上找女朋友,坐标上海,非诚勿扰,vx:fan404006308
AI交流资料群:753014672