美文网首页javascript
JavaScript promise 常见用法

JavaScript promise 常见用法

作者: 暴躁程序员 | 来源:发表于2023-05-14 11:21 被阅读0次

    promise 的出现是为了解决回调函数的两个常见问题

    // 回调函数问题
    问题一:回调函数多层嵌套调用(回调地狱)
    问题二:每次回调的结果存在成功或失败的可能性
    
    // 使用 promise 解决
    解决问题一:promise 通过 .then 实现链式调用
    解决问题二:promise 通过 .catch 统一捕获异常
    

    1. promise对象上的 then、catch、finally 方法

    1. .then(回调函数) : resolve(e) 出口,可链式调用
    2. .catch(回调函数) :reject(e) 出口或者用于捕获程序异常
    3. .finally(回调函数):总是在最后执行
    1. 新建 promise.js
    const getData = (params) => {
      return new Promise((resolve, reject) => {
        // throw new Error() // 可被 catch 捕获
        if (params?.id) {
          setTimeout(() => {
            resolve({
              errorCode: "0",
              data: {
                id: params.id,
                message: "hello promise",
              },
            });
          }, 1000);
        } else {
          setTimeout(() => {
            reject({
              errorCode: "-1",
              data: {
                message: "no params",
              },
            });
          }, 1000);
        }
      });
    };
    
    const params = { id: 1 }
    getData(params)
      .then((res) => {
        console.log('res',res); 
      })
      .catch((err) => {
        console.log('err',err); 
      })
      .finally(() => {
        console.log("我是 finally 总是最后执行");
      });
    
    1. 终端执行
    node promise.js 
    
    1. 结果
    // 2s 后
    res { errorCode: '0', data: { id: 1, message: 'hello promise' } }
    我是 finally 总是最后执行
    

    2. promise 对象简化写法,Promise.resolve()、Promise.reject()

    1. 新建 promise.js
    const resolve = Promise.resolve("hello Promise.resolve");
    resolve.then((res) => {
      console.log(res);
    });
    const reject = Promise.reject("hello Promise.reject");
    reject.catch((err) => {
      console.log(err);
    });
    
    1. 终端执行
    node promise.js 
    
    1. 结果
    hello Promise.resolve
    hello Promise.reject
    

    3. 等所有 promise 异步执行完毕统一返回结果(短路),Promise.all([p1,p2,p3])

    1. Promise.all() 接受一个由promise对象组成的数组:如果传入函数返回的promise对象,需要传入函数立即执行后的结果
    2. 特点:短路,必须所有的都是 resolve 否则才返回所有结果,否则发现第一个 reject 就直接返回那个 reject的结果
    3. 获取结果(全部 resolve):按照 [fn1,fn2,fn3] 传参时的顺序,以数组的方式返回结果(不是按响应的时间顺序返回结果)
    1. 新建 promise.js
    console.log('start');
    const p1 = (() => {
      return new Promise((resolve, reject) => {
        console.log("p1");
        const status = true;
        if (status) {
          setTimeout(() => {
            resolve("p1:成功");
          }, 1000);
        } else {
          setTimeout(() => {
            reject("p1:失败");
          }, 1000);
        }
      });
    })();
    
    const p2 = new Promise((resolve, reject) => {
      console.log('p2');
    
      const status = true;
      if (status) {
        setTimeout(() => {
          resolve("p2:成功");
        }, 3000);
      } else {
        setTimeout(() => {
          reject("p2:失败");
        }, 1000);
      }
    });
    
    const p3 = new Promise((resolve, reject) => {
      console.log('p3');
    
      const status = true;
      if (status) {
        setTimeout(() => {
          resolve("p3:成功");
        }, 2000);
      } else {
        setTimeout(() => {
          reject("p3:失败");
        }, 2000);
      }
    });
    
    Promise.all([p1, p2, p3])
      .then((res) => {
        console.log('res',res); 
      })
      .catch((err) => {
        console.log('err',err); 
      });
    
    1. 终端执行
    node promise.js 
    
    1. 结果
    // 立即打印
    start
    p1
    p2
    p3
    // 3s 后
    res [ 'p1:成功', 'p2:成功', 'p3:成功' ]
    

    4. 等所有 promise 异步执行完毕统一返回结果,Promise.allSettled([p1,p2,p3])

    1. Promise.allSettled() 接受一个由promise对象组成的数组:如果传入函数返回的promise对象,需要传入函数立即执行后的结果
    2. 特点:解决 Promise.all 短路问题
    3. 获取结果:此方法解决了 Promise.all() 短路的问题,不管是 resolve 还是 reject,都会按照 [fn1,fn2,fn3] 传参时的顺序,以数组的方式将状态和数据放入对象中统一返回
    1. 新建 promise.js
    console.log('start');
    const p1 = (() => {
      return new Promise((resolve, reject) => {
        console.log("p1");
        const status = true;
        if (status) {
          setTimeout(() => {
            resolve("p1:成功");
          }, 1000);
        } else {
          setTimeout(() => {
            reject("p1:失败");
          }, 1000);
        }
      });
    })();
    
    const p2 = new Promise((resolve, reject) => {
      console.log('p2');
    
      const status = true;
      if (status) {
        setTimeout(() => {
          resolve("p2:成功");
        }, 3000);
      } else {
        setTimeout(() => {
          reject("p2:失败");
        }, 1000);
      }
    });
    
    const p3 = new Promise((resolve, reject) => {
      console.log('p3');
    
      const status = false;
      if (status) {
        setTimeout(() => {
          resolve("p3:成功");
        }, 2000);
      } else {
        setTimeout(() => {
          reject("p3:失败");
        }, 2000);
      }
    });
    
    Promise.allSettled([p1, p2, p3])
      .then((res) => {
        console.log('res',res); 
      })
      .catch((err) => {
        console.log('err',err); 
      });
    
    1. 终端执行
    node promise.js 
    
    1. 结果
    // 立即打印
    start
    p1
    p2
    p3
    // 3s 后
    res [
      { status: 'fulfilled', value: 'p1:成功' },
      { status: 'fulfilled', value: 'p2:成功' },
      { status: 'rejected', reason: 'p3:失败' }
    ]
    

    5. 不等所有 promise 异步执行完毕,只是返回响应最快的 promise 结果,Promise.race([p1,p2,p3])

    1. Promise.race() 接受一个由promise对象组成的数组:如果传入函数返回的promise对象,需要传入函数立即执行后的结果
    2. 获取结果:不管是 resolve 还是 reject,只是返回响应最快的 promise 结果
    1. 新建 promise.js
    console.log('start');
    const p1 = (() => {
      return new Promise((resolve, reject) => {
        console.log("p1");
        const status = true;
        if (status) {
          setTimeout(() => {
            resolve("p1:成功");
          }, 1000);
        } else {
          setTimeout(() => {
            reject("p1:失败");
          }, 1000);
        }
      });
    })();
    
    const p2 = new Promise((resolve, reject) => {
      console.log('p2');
    
      const status = true;
      if (status) {
        setTimeout(() => {
          resolve("p2:成功");
        }, 3000);
      } else {
        setTimeout(() => {
          reject("p2:失败");
        }, 1000);
      }
    });
    
    const p3 = new Promise((resolve, reject) => {
      console.log('p3');
    
      const status = false;
      if (status) {
        setTimeout(() => {
          resolve("p3:成功");
        }, 2000);
      } else {
        setTimeout(() => {
          reject("p3:失败");
        }, 2000);
      }
    });
    
    Promise.race([p1, p2, p3])
      .then((res) => {
        console.log('res',res); 
      })
      .catch((err) => {
        console.log('err',err); 
      });
    
    1. 终端执行
    node promise.js 
    
    1. 结果
    // 立即打印
    start
    p1
    p2
    p3
    // 3s 后
    res p1:成功
    

    相关文章

      网友评论

        本文标题:JavaScript promise 常见用法

        本文链接:https://www.haomeiwen.com/subject/azcpsdtx.html