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   })
 
原文地址:https://www.cnblogs.com/Renyi-Fan/p/12776433.html