promise简单入门

78 阅读5分钟

一. 问题:

  • 当B请求需要A请求的结果作为参数时, B需要等A有了请求结果之后才能进行请求,
  • 如果嵌套着写会造成难以阅读的回调地狱
// 模拟 需要感觉用户名字才能获取用户信息
// 当获取名字比较慢的时候, 则无法继续执行下面的函数
let name;
let info;

function getName() {
  setTimeout(() => {
    name = '勿悸';
    console.log('获取用户名字');
  }, 2000)
}

function getInfo() {
  setTimeout(() => {
    if (name) {
      console.log(name);
      info = {
        age: 17,
        sex: 'male',
      }
      console.log('根据名字获取用户信息');
    }
  }, 1000)
}

function getAge() {
  setTimeout(() => {
    if (info) {
      console.log(info.age);
      console.log('在用户信息找出年龄');
    }
  }, 1000)
}

getName()
getInfo()
getAge()


// 回调地狱 非常难看懂;
function run() {
  setTimeout(() => {
    name = '勿悸';
    console.log('获取用户名字');
    setTimeout(() => {
      if (name) {
        console.log(name);
        info = {
          age: 17,
          sex: 'male',
        }
        console.log('根据名字获取用户信息');
        setTimeout(() => {
          if (info) {
            console.log(info.age);
            console.log('在用户信息找出年龄');
          }
        }, 1000)
      }
    }, 1000)
  }, 2000)
}

run()

二. promise使用方法

promise的三个状态 分别是pending(待定), fulfilled(已兑现), rejected(已拒绝).

  • pending(待定),执行了executor,状态还在等待中,没有被兑现,也没有被拒绝
  • 当promise对象从pending(待定) --> fulfilled(已兑现)时,执行了resolve回调函数
  • 当promise对象从pending(待定) --> rejected(已拒绝)时,执行了reject回调函数
  • resolve回调函数由.then传入, reject回调函数由.catch传入
// 模拟是否请求成功
const isSuccess = true;

// 1.此时new出来的promise的状态为等待态(Pending);
const promise = new Promise((resolve, reject) => {
  // 2.模拟请求: 当请求结束后promise的状态将转为fulfilled(已兑现)或rejected(已拒绝)
  setTimeout(() => {
    if (isSuccess) {
      resolve('请求成功')
    } else {
      reject('请求失败')
     }
  }, 1000);

});

// Promise 有三种状态: 等待态(Pending)、执行态(Fulfilled)和拒绝态(Rejected)
// 此时new出来的promise的状态为等待态(Pending);
promise
  .then((res) => {
    // 3.1 当promise的状态将转为fulfilled(已兑现)时,将执行.then传入的回调函数
    console.log(res);
  })
  .catch((res) => { 
    // 3.2 当promise的状态将转为或rejected(已拒绝)时,将执行.catch传入的回调函数
    console.log(res);
  })

三. promise的链式调用

// 模拟是否请求成功
const isSuccess = true;

const promise = new Promise((resolve, reject) => {
  // 模拟请求
  setTimeout(() => {
    if (isSuccess) {
      resolve('请求成功')
    } else {
      reject('请求失败')
     }
  }, 1000);

});

// 若有一次.then没有执行则跳过接下来的所有then 执行catch
promise
  .then((res) => { 
    console.log(res);
    const promise2 = new Promise((resolve, reject) => {
      // 模拟请求
      setTimeout(() => {
        if (isSuccess) {
          resolve('第二次请求成功')
        } else {
          reject('第二次请求失败')
        }
      }, 1000);
    }); 
    return promise2;
  })
  .then((res) => { 
    console.log(res);
  })
  .catch((res) => { 
    console.log(res);
  })

四. 解决问题

// 模拟 需要感觉用户名字才能获取用户信息
// 当获取名字比较慢的时候, 则无法继续执行下面的函数
let name;
let info;

const getName = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      name = '勿悸';
      console.log('获取用户名字');
      resolve(name)
    }, 2000)
  })
}

const getInfo = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      if (name) {
        console.log(name);
        info = {
          age: 17,
          sex: 'male',
        }
        console.log('根据名字获取用户信息');
      resolve(info)
      }
    }, 1000)
  })
}

const getAge = () => {
  new Promise((resolve, reject) => {
    setTimeout(() => {
      if (info) {
        console.log('在用户信息找出年龄');
        resolve(info.age);
      }
    }, 1000)
  })
}


getName()
  .then(res => {
    return getInfo()
  })
  .then(res => {
    return getAge()
  })


五. Promise的静态方法


const promisePending1 = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      // 停留在pending(待定)状态的promise1
    }, 1000)
  })
}
const promisePending2 = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      // 停留在pending(待定)状态的promise2
    }, 1000)
  })
}
const promisePending3 = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      // 停留在pending(待定)状态的promise3
    }, 1000)
  })
}

const promiseResolve1 = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('转为fulfilled(已兑现)状态的promise1')
    }, 1000)
  })
}
const promiseResolve2 = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('转为fulfilled(已兑现)状态的promise2')
    }, 1000)
  })
}
const promiseResolve3 = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('转为fulfilled(已兑现)状态的promise3')
    }, 1000)
  })
}

const promiseReject1 = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject('转为rejected(已拒绝)状态的promise1')
    }, 1000)
  })
}
const promiseReject2 = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject('转为rejected(已拒绝)状态的promise2')
    }, 1000)
  })
}
const promiseReject3 = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      reject('转为rejected(已拒绝)状态的promise3')
    }, 1000)
  })
}



// .reject()
Promise.reject()
  .catch(error => {
    console.log('.reject()直接返回一个rejected(已拒绝)状态的promise对象');
  })


// .resolve()
Promise.resolve(promisePending1)
  .then(res => {
    console.log('.resolve()参数传入promise对象, 则直接返回该对象');
  })

const obj = {
  then: () => {
    console.log('.resolve()参数传入一个具有then方法的对象, 会将对象转为promise对象 并立即执行then方法 ');
  }
}
Promise.resolve(obj)

Promise.resolve('hello')
  .then(res => {
    console.log('.resolve()参数传入一个没有then方法的对象或非对象 返回一个状态为fulfilled(已兑现)的promise对象且将参数传入下一个then', res);
  })

Promise.resolve()
  .then(res => {
    console.log('.resolve()不传参数返回一个状态为fulfilled(已兑现)的promise对象');
  })

// .all() 全部转为fulfilled(已兑现)
Promise.all([promiseResolve1(), promiseResolve2(), promiseResolve3()])
  .then(res => {
    console.log('.all()全部转为fulfilled(已兑现)才会调用then方法');
  })

Promise.all([promiseResolve1(), promiseResolve2(), promisePending1()])
  .finally(res => {
    console.log('.all()有任何一个为Pending状态 则依旧为Pending状态');
  })

Promise.all([promiseResolve1(), promiseResolve2(), promiseReject1()])
  .then(res => {
    console.log('.all()有任何一个没转为fulfilled(已兑现)则不执行then方法');
  })
  .catch(error => {
    console.log('.all()有任何一个没转为fulfilled(已兑现) 则执行catch方法, 且只报第一个promise', error);
  })

// .allSettled() allSettled()所有的promise都执行了
Promise.allSettled([promiseResolve1(), promiseResolve2(), promisePending1()])
  .finally(res => {
    console.log('.allSettled()有任何一个为Pending状态 则依旧为Pending状态');
  })

Promise.allSettled([promiseResolve1(), promiseResolve2(), promiseReject1()])
  .then(res => {
    console.log('.allSettled()所有的promise都执行了, 则执行then方法');
  })


// .any() 任何一个promise转为fulfilled(已兑现)状态
Promise.any([promiseResolve1(), promiseReject1(), promisePending1()])
  .then(res => {
    console.log('.any()有任何一个promise转为fulfilled(已兑现)状态 则执行then方法');
  })

Promise.any([promiseReject1(), promiseReject2(), promisePending1()])
  .finally(res => {
    console.log('.any()存在promise为pending  则保持为Pending状态');
  })


Promise.any([promiseReject1(), promiseReject2(), promiseReject3()])
  .then(res => {
    console.log('--------');
  })
  .catch(res => {
    console.log('.any()没有一个转为fulfilled(已兑现)状态且都执行了, 则执行catch');
  })

// race() 任何一个promise执行
Promise.race([promiseResolve1(), promisePending1(), promisePending2()])
  .then(res => {
    console.log('.race()有任何一个promise转为fulfilled(已兑现)或rejected(已拒绝)状态 则执行then方法');
  })

Promise.race([promiseReject1(), promisePending1(), promisePending2()])
  .then(res => {
    console.log('.race()有任何一个promise转为fulfilled(已兑现)或rejected(已拒绝)状态 则执行then方法');
  })
  .catch(error => {
    console.log('.race()有任何一个promise转为rejected(已拒绝)状态 也执行catch方法', error);
  })