一、promise基本概念

1.1 回调问题

在平常敲代码中经常会遇到多层回调函数的相互嵌套问题。如下:

grpc 回调过程_异步操作

这会使得代码耦合性太强,牵一发而动全身,难以维护 。大量冗余的代码相互嵌套,代码的可读性变差。

1.2 如何解决回调问题


为了解决回调过深的问题, ES6 (ECMAScript 2015)中新增了 Promise 的概念。



1.3 Promise 的基本概念


 Promise 是一个构造函数




我们可以创建 Promise 的实例 const p = new Promise()




         new 出来的 Promise 实例对象, 代表一个异步操作



二、Promise.then()

Promise.prototype 上包含一个 .then() 方法


         每一次 new Promise() 构造函数得到的实例对象,都可以通过原型链的方式访问到 .then() 方法,例如 p.then()。



then() 方法用来预先指定成功和失败的回调函数



then()方法是异步执行。意思是:就是当.then()前的方法执行完后再执行then()内部的程序,这样就避免了,数据没获取到等的问题。


 a. p.then(成功的回调函数,失败的回调函数)




 b. p.then(result => { }, error => { })




 c. 调用 .then() 方法时,成功的回调函数是必选的、失败的回调函数是可选的




一个简单的读取文件例子:



thenFs.readFile('./files/1.txt', 'utf8').then((r1) => { console.log(r1) })//111




三、Promise链式调用

 3.1 .then()方法特性

  promise支持链式调用。如果上一个 .then() 方法中返回了一个新的 Promise 实例对象,则可以通过下一个 .then() 继续进行处理。通 过 .then() 方法的链式调用,就解决了回调过深的问题。

就例如想要按顺序读取文件内容:


import thenFs from "then-fs";

thenFs.readFile('./files/1.txt', 'utf8')
    .then((r1) => {
        console.log(r1);
        return thenFs.readFile('./files/2.txt', 'utf8')
    }).then((r2) => {
        console.log(r2);
        return thenFs.readFile('./files/33.txt', 'utf8')
    }).then((r3) => {
        console.log(r3);
    })

通过链式调用姐简洁的实现了按顺序读取文件1,2,3的内容 。

四、Promise.catch()



通过 .catch 捕获错误




        在 Promise 的链式操作中如果发生了错误,可以使用 Promise.prototype. catch 方法进行捕获和处理:





thenFs.readFile('./files/11.txt', 'utf8')//(文件路径错误,导致后面3个.then()都无法执行)
    .then((r1) => {
        console.log(r1);
        return thenFs.readFile('./files/2.txt', 'utf8')
    }).then((r2) => {
        console.log(r2);
        return thenFs.readFile('./files/33.txt', 'utf8')
    }).then((r3) => {
        console.log(r3);
    }).catch((err) => {   // 捕获第一行错误 输出错误内容
        console.log(err.message);
    })

如果不希望前面的错误导致后续的 .then 无法正常执行,则可以将 .catch 的调用提前,示例代码如下:

thenFs.readFile('./files/11.txt', 'utf8')
    .catch((err) => {   //捕获异常错误   提前捕获  可继续执行
        console.log(err.message);
    })
    .then((r1) => {
        console.log(r1);
        return thenFs.readFile('./files/2.txt', 'utf8')
    }).then((r2) => {
        console.log(r2);
        return thenFs.readFile('./files/33.txt', 'utf8')
    }).then((r3) => {
        console.log(r3);
    })

五、Promise.all()和Promise.race() 方法

Promise.all() 方法会发起并行的 Promise 异步操作,等所有的异步操作全部结束后才会执行下一步的 .then 操作(等待机制)。



        Promise.race() 方法会发起并行的 Promise 异步操作, 只要任何一个异步操作完成,就立即执行下一步的 .then 操作 (赛跑机制)。



示例代码如下:

import thenFs from "then-fs";

const promiseArr = [
    thenFs.readFile('./files/1.txt', 'utf8'),
    thenFs.readFile('./files/2.txt', 'utf8'),
    thenFs.readFile('./files/3.txt', 'utf8')
]

// Promise.all(promiseArr).then((result) => {   //所有完成才返回
Promise.race(promiseArr).then((result) => {   //有一个完成了就返回
    console.log(result);
})