前端Vue日常工作中--Promise

前端Vue日常工作中--Promise

Promise 是 JavaScript 中用于处理异步操作的一种机制,它的主要目的是更好地组织和管理异步代码。Promise 对象有三个状态:pending(进行中)、fulfilled(已成功)和 rejected(已失败)。一旦 Promise 的状态变为 fulfilledrejected,就称为 Promise 已经 settled(已定型),这时可以通过 then 方法来处理对应的状态。

1.基本说明

一个 Promise 可以处于以下三种状态之一:

  • Pending(进行中): 初始状态,表示异步操作还在进行中,未完成。
  • Fulfilled(已成功): 表示异步操作成功完成,此时会调用 resolve 函数,并将结果传递给成功的处理函数。
  • Rejected(已失败): 表示异步操作失败,此时会调用 reject 函数,并将错误信息传递给失败的处理函数。

1.1Promise 的基本结构

一个 Promise 对象可以通过 new Promise() 来创建,其构造函数接受一个带有 resolvereject 两个参数的函数,表示异步操作的结果。

javascript 复制代码
const myPromise = new Promise((resolve, reject) => {
  // 异步操作,例如网络请求、定时器等

  // 异步操作成功时调用 resolve
  resolve('Success!');

  // 异步操作失败时调用 reject
  // reject('Error!');
});

1.2Promise 的状态转换

Promise 的状态是可以从 pending 转变为 fulfilledrejected 的,但一旦转变了就不可再变。

javascript 复制代码
// 创建一个 pending 状态的 Promise 对象
const myPromise = new Promise((resolve, reject) => {
  // 异步操作,例如网络请求、定时器等

  // 异步操作成功时调用 resolve
  resolve('Success!');

  // 异步操作失败时调用 reject
  // reject('Error!');
});

// 使用 then 处理成功的情况
myPromise.then((result) => {
  console.log(result); // 输出: Success!
});

// 使用 catch 处理失败的情况
myPromise.catch((error) => {
  console.error(error); // 输出: Error!
});

1.3Promise 链式调用

Promise 提供了链式调用的方式,通过 then 方法可以在一个 Promise 的成功状态处理函数中返回另一个 Promise,实现连续的异步操作。

javascript 复制代码
const myPromise = new Promise((resolve, reject) => {
  // 异步操作,例如网络请求、定时器等
  resolve('Step 1');
});

myPromise
  .then((result) => {
    console.log(result); // 输出: Step 1
    return 'Step 2';
  })
  .then((result) => {
    console.log(result); // 输出: Step 2
    throw new Error('Error in Step 2');
  })
  .catch((error) => {
    console.error(error.message); // 输出: Error in Step 2
  });

then 方法返回的是一个新的 Promise,这使得我们可以通过链式调用来处理连续的异步操作。

1.4Promise.all 和 Promise.race

Promise.all 可以接受一个 Promise 数组,并在所有 Promise 都成功时返回一个包含所有结果的数组,任何一个 Promise 失败则直接触发失败。

javascript 复制代码
const promise1 = Promise.resolve('One');
const promise2 = new Promise((resolve) => setTimeout(() => resolve('Two'), 2000));
const promise3 = Promise.reject(new Error('Three'));

Promise.all([promise1, promise2, promise3])
  .then((results) => {
    console.log(results); // 任何一个 Promise 失败都不会执行到这里
  })
  .catch((error) => {
    console.error(error.message); // 输出: Three
  });

Promise.race 则在第一个 Promise 变为 settled(已定型)时返回它的结果或错误,无论是成功还是失败。

javascript 复制代码
const promise1 = new Promise((resolve) => setTimeout(() => resolve('One'), 3000));
const promise2 = new Promise((resolve) => setTimeout(() => resolve('Two'), 2000));

Promise.race([promise1, promise2])
  .then((result) => {
    console.log(result); // 输出: Two
  })
  .catch((error) => {
    console.error(error.message); // 不会执行到这里
  });

1.5Promise 的错误处理

catch 方法可以来处理 Promise 异步操作失败的情况。此外,还可以在 then 方法中的第二个参数中处理失败的情况,这样可以更灵活地分别处理成功和失败的结果。

javascript 复制代码
const myPromise = new Promise((resolve, reject) => {
  // 异步操作,例如网络请求、定时器等
  reject(new Error('Failed!'));
});

myPromise
  .then(
    (result) => {
      console.log(result); // 不会执行到这里
    },
    (error) => {
      console.error(error.message); // 输出: Failed!
    }
  );

1.6异步任务的串行执行

Promise 的串行执行是通过链式调用 then 方法来实现的。每个 then 方法都返回一个新的 Promise 对象,使得可以依次串联多个异步任务。

javascript 复制代码
const asyncTask1 = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('Async Task 1');
      resolve('Task 1 Result');
    }, 1000);
  });
};

const asyncTask2 = () => {
  return new Promise((resolve) => {
    setTimeout(() => {
      console.log('Async Task 2');
      resolve('Task 2 Result');
    }, 500);
  });
};

asyncTask1()
  .then((result1) => {
    console.log(result1);
    return asyncTask2();
  })
  .then((result2) => {
    console.log(result2);
  });

asyncTask2asyncTask1 执行成功后才会执行,实现了异步任务的串行执行。

1.7使用 Promise.resolve 和 Promise.reject

Promise.resolvePromise.reject 是两个快捷方法,用于创建已经定型的 Promise 对象。

javascript 复制代码
const resolvedPromise = Promise.resolve('Resolved Data');
const rejectedPromise = Promise.reject(new Error('Rejected Error'));

resolvedPromise.then((data) => console.log(data)); // 输出: Resolved Data
rejectedPromise.catch((error) => console.error(error.message)); // 输出: Rejected Error

1.8async/await 与 Promise 结合使用

ES2017 引入了 async/await 语法,它建立在 Promise 的基础上,提供一种更清晰、更同步化的方式来处理异步操作。

javascript 复制代码
async function fetchData() {
  try {
    const result1 = await asyncTask1();
    console.log(result1);

    const result2 = await asyncTask2();
    console.log(result2);
  } catch (error) {
    console.error(error.message);
  }
}

fetchData();

async/await 使得异步代码看起来更像同步代码,提高了代码的可读性。

2.父子组件中使用

在Vue中,父子组件之间的通信可以使用Promise来实现异步操作的协调。在父组件中调用子组件的方法,并使用Promise来处理异步操作:

父组件

html 复制代码
<template>
  <div>
    <h1>Parent Component</h1>
    <button @click="getDataFromChild">Get Data from Child</button>
    <Child ref="childComponent"></Child>
  </div>
</template>

<script>
import Child from './Child.vue';

export default {
  components: {
    Child,
  },
  methods: {
    getDataFromChild() {
      // 调用子组件的方法,并返回一个Promise对象
      const promiseFromChild = this.$refs.childComponent.getChildData();

      promiseFromChild.then((data) => {
        console.log('Data received from child:', data);
      }).catch((error) => {
        console.error('Error from child:', error);
      });
    },
  },
};
</script>

子组件

html 复制代码
<template>
  <div>
    <h2>Child Component</h2>
  </div>
</template>

<script>
export default {
  methods: {
    getChildData() {
      // 模拟异步操作,例如网络请求
      return new Promise((resolve, reject) => {
        setTimeout(() => {
          const data = 'Data from child component';
          // 成功时调用resolve,将数据传递给父组件
          resolve(data);
          
          // 如果异步操作失败,调用reject
          // reject(new Error('Error in child component'));
        }, 2000);
      });
    },
  },
};
</script>

父组件包含一个按钮,点击按钮后会调用 子组件的 getChildData 方法。getChildData 方法返回一个Promise对象,通过setTimeout模拟了一个异步操作。当异步操作完成时,会调用resolve方法,将数据传递给父组件。

父组件通过 then 方法处理异步操作成功的情况,通过 catch 方法处理异步操作失败的情况。通过Promise来实现父子组件的异步通信,可以更好地管理异步代码,提高代码的可读性和可维护性。

3.Promise作用总结

Promise 在 JavaScript 中的作用主要是用于处理异步操作,提供了一种更结构化、更可读的方式来编写异步代码。

  1. 更清晰的异步代码: Promise 提供了一种链式调用的方式,使得异步操作的代码更具可读性。通过使用 thencatch 方法,可以清晰地处理异步操作的成功和失败情况。

  2. 避免回调地狱: 传统的回调函数嵌套容易导致回调地狱(callback hell),代码难以阅读和维护。Promise 的链式调用可以避免这种情况,使得异步代码更加结构化。

  3. 更好的错误处理: Promise 提供了 catch 方法来专门处理异步操作中的错误,使得错误处理更为集中和清晰。而且可以使用 finally 方法在不管 Promise 是成功还是失败的情况下执行一段代码。

  4. 异步操作的状态管理: Promise 有三种状态(pending、fulfilled、rejected),这种状态管理使得异步操作更加可控。一旦 Promise 的状态变为 fulfilledrejected,就称为 Promise 已经 settled(已定型)。

  5. 方便的异步串行执行: 通过链式调用 then 方法,可以实现异步任务的串行执行,使得异步操作按照特定的顺序执行,而不是并发执行。

  6. Promise.all 和 Promise.race: 提供了 Promise.allPromise.race 两个方法,用于处理多个异步操作。Promise.all 在所有 Promise 都成功时返回一个包含所有结果的数组,而 Promise.race 在第一个 Promise 变为 settled(已定型)时返回它的结果或错误。

  7. 更好的异步错误堆栈信息: 使用 Promise,可以更方便地追踪异步错误的来源,因为错误会被传递到 catch 方法,而不会被隐式地丢失。

相关推荐
GISer_Jing2 小时前
前端面试通关:Cesium+Three+React优化+TypeScript实战+ECharts性能方案
前端·react.js·面试
落霞的思绪3 小时前
CSS复习
前端·css
咖啡の猫5 小时前
Shell脚本-for循环应用案例
前端·chrome
百万蹄蹄向前冲7 小时前
Trae分析Phaser.js游戏《洋葱头捡星星》
前端·游戏开发·trae
朝阳5818 小时前
在浏览器端使用 xml2js 遇到的报错及解决方法
前端
GIS之路8 小时前
GeoTools 读取影像元数据
前端
ssshooter9 小时前
VSCode 自带的 TS 版本可能跟项目TS 版本不一样
前端·面试·typescript
Jerry9 小时前
Jetpack Compose 中的状态
前端
dae bal10 小时前
关于RSA和AES加密
前端·vue.js
柳杉10 小时前
使用three.js搭建3d隧道监测-2
前端·javascript·数据可视化