前端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 方法,而不会被隐式地丢失。

相关推荐
dy17173 小时前
element-plus表格默认展开有子的数据
前端·javascript·vue.js
2501_915918416 小时前
Web 前端可视化开发工具对比 低代码平台、可视化搭建工具、前端可视化编辑器与在线可视化开发环境的实战分析
前端·低代码·ios·小程序·uni-app·编辑器·iphone
程序员的世界你不懂7 小时前
【Flask】测试平台开发,新增说明书编写和展示功能 第二十三篇
java·前端·数据库
索迪迈科技7 小时前
网络请求库——Axios库深度解析
前端·网络·vue.js·北京百思可瑞教育·百思可瑞教育
gnip7 小时前
JavaScript二叉树相关概念
前端
attitude.x8 小时前
PyTorch 动态图的灵活性与实用技巧
前端·人工智能·深度学习
β添砖java8 小时前
CSS3核心技术
前端·css·css3
空山新雨(大队长)8 小时前
HTML第八课:HTML4和HTML5的区别
前端·html·html5
猫头虎-前端技术9 小时前
浏览器兼容性问题全解:CSS 前缀、Grid/Flex 布局兼容方案与跨浏览器调试技巧
前端·css·node.js·bootstrap·ecmascript·css3·媒体