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

相关推荐
Martin -Tang27 分钟前
vite和webpack的区别
前端·webpack·node.js·vite
迷途小码农零零发28 分钟前
解锁微前端的优秀库
前端
王解1 小时前
webpack loader全解析,从入门到精通(10)
前端·webpack·node.js
我不当帕鲁谁当帕鲁1 小时前
arcgis for js实现FeatureLayer图层弹窗展示所有field字段
前端·javascript·arcgis
那一抹阳光多灿烂1 小时前
工程化实战内功修炼测试题
前端·javascript
放逐者-保持本心,方可放逐2 小时前
微信小程序=》基础=》常见问题=》性能总结
前端·微信小程序·小程序·前端框架
毋若成4 小时前
前端三大组件之CSS,三大选择器,游戏网页仿写
前端·css
红中马喽4 小时前
JS学习日记(webAPI—DOM)
开发语言·前端·javascript·笔记·vscode·学习
Black蜡笔小新5 小时前
网页直播/点播播放器EasyPlayer.js播放器OffscreenCanvas这个特性是否需要特殊的环境和硬件支持
前端·javascript·html
秦jh_6 小时前
【Linux】多线程(概念,控制)
linux·运维·前端