Promise的基本用法

273 阅读4分钟

promise的作用

Promise对象可以理解为一次执行的异步操作,解决回调地狱的问题

promise的特点

Promise有三种状态(pending等待、resolve成功、reject失败)

  • 对象的状态不受外界影响
  • 一旦状态改变,就不会再变,任何时候都可以得到这个结果

基本用法

/*
Promise构造函数接受一个函数作为参数,函数中有两个形参分别是resolve函数和reject函数
    reslove函数:将Promise对象的状态从“等待”变为“成功”(从 pending 变为 resolved)。异步操作成功时调用,并将异步操作的结果作为参数传递出去
    reject函数:将Promise对象的状态从“等待”变为“失败”(从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去
*/
    const promise = new Promise((resolve, reject) => {
      if (true) {
        // 接口请求成功时调用
        resolve('成功');
      } else {
        // 接口请求失败时调用
        reject('失败');
      }
    });
    
    /* Promise实例生成以后,可以用  .then 方法指定resolved状态.用  .catch  方法 rejected状态的回调函 */
    //  data 就是 从 resolve 和 reject 返回的结果
    promise.then(data => {
      console.log(data);
    }).catch(err => {
      console.log(err);
    });

.then()方法

用于预先指定成功失败的回调函数

/*   p.then(成功的回调函数,[失败的回调函数])  成功的回调函数是必选的*/
p.then(res=>{}[,err=>{}])

.then的链式调用

.then() 方法有一个特性。如果上一个 .then 方法中返回一个新的 Promise实例对象,则可以通过下一个 .then 方法继续处理

/* 需求:
    按顺序读取文件内容
*/

// 导入第三方包 then-fs----可以异步读取文件的内容,且返回值为   promise实例对象
import thenFs from "then-fs"

// 通过promise的特性-----链式调用(只要上一个 .then 方法中返回一个新的promise实例对象就可以使用链式调用)
thenFs.readFile("./test/1.txt", "utf-8")
    .then(result1 => {
        console.log(result1);
        return thenFs.readFile("./test/2.txt", "utf-8")
    })
    .then(result2 => {
        console.log(result2);
        return thenFs.readFile("./test/3.txt", "utf-8")
    })
    .then(result3 => {
        console.log(result3);
    })

.ctach()方法

.catch() 方法用于在 Promise 的链式操作中,如果发生了错误,可以使用 promise.prototype.catch() 方法进行捕获错误和处理,只要在操作中发生了错误就会立刻调用 .catch 方法

/ 假设在当前目录下不存在 11111.txt 文件,此时因文件不存在导致读取文件失败,而不会执行当前 .then 里面的代码
thenFs.readFile("./test/11111.txt", "utf-8")
	/*如果把catch放在这个位置,因为当前只有第一个.then 发生了错误,此时已经被处理了,后面 .then 能够正常执行
	.catch(err=>{
         console.log(err.message);
     })
    */
     .then(result1 => {
         console.log(result1);
         return thenFs.readFile("./test/2.txt", "utf-8")
     })
     .then(result2 => {
         console.log(result2);
         return thenFs.readFile("./test/3.txt", "utf-8")
     })
     .then(result3 => {
         console.log(result3);
     })
// 通过 .catch 方法捕获所有的错误,只要在操作中发生了错误就会立刻调用  .catch  方法,并且在发生错误后面的then都不会在执行
     .catch(err=>{
         console.log(err.message);
     })

Promise.finally()

不管promise最后的状态(无论成功还是失败),在执行完then或catch指定的回调函数以后,都会执行finally方法指定的回调函数

function getList(flag){
  return new Promise((resolve,reject)=>{
    flag ? resolve('ok') : reject(err)
  })
  .then(res=>{})
  .catch(err=>{})
  .finally(()=>{})
}

Promise.all()方法(等待)

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

/ 定义一个数组,存放三个异步读取文件内容的的操作
const promiseArr = [
    thenFs.readFile("./test/1.txt", "utf8"),
    thenFs.readFile("./test/2.txt", "utf8"),
    thenFs.readFile("./test/3.txt", "utf8")
]

// 调用 Promise.all() 方法,将 promiseArr 数组作为参数。此时当全部的异步操作执行结束后再去执行 then 操作
Promise.all(promiseArr)
    .then((result) => {   // 所有文件 读取成功才会执行 .then 方法,且读取的顺序就是最后结果的是顺序
        console.log(result);
    })
    .catch(err => { // 捕获 promise 中的异步操作的错误
        console.log(err.message);
    })

Promise.race()方法(赛跑)

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

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

// Promise.race()方法只要有任意一个异步操作完成就会执行 then 操作(这里就看哪个文件优先读取成功),只会返回读取最快的结果
Promise.race(promiseArr)
    .then(result => {
        console.log(result);
    })
    .catch(err => {
        console.log(err.message);
    })