Promise、async/await 的使用

Promiseasync/await 的使用

目录

  1. Promise
  2. async/await

Promise

什么是 Promise

Promise 是异步编程的一种解决方案,它代表了一个异步操作的最终结果。它是一个对象,用来传递异步操作的消息,而不是直接传递结果。

Promise 提供统一的 API,各种异步操作都可以用同样的方法进行处理,并提供统一的接口。Promise 也有三种状态:

  • Pending(等待中):初始状态,既没有完成也没有失败。
  • Fulfilled(已完成):操作成功完成。
  • Rejected(已失败):操作失败。

Promise 的特点

  • 对象的状态不受外界影响。Promise 实例代表一个异步操作,有三种状态,分别是 Pending(等待中)、Fulfilled(已完成)和 Rejected(已失败)。只有异步操作的结果,才会改变 Promise 的状态。
  • 一旦状态改变,就不会再变,任何时候都可以得到这个结果。Promise 实例代表的异步操作,一旦异步操作完成,就不会再变,任然是 Pending 状态。
  • Promise 对象的 then 方法是定义在原型上面的,可以把多个 Promise 实例进行链式调用。
  • Promise 对象的 catch 方法是定义在原型上面的,可以捕获 Promise 实例中发生的错误。
  • Promise 对象的 finally 方法是定义在原型上面的,不管 Promise 实例最后状态如何,都会执行指定的回调函数。
  • Promise 实例的构造函数接受一个执行器函数,该函数的两个参数分别是 resolverejectresolve 用于将 Promise 对象的状态从 Pending 变为 Fulfilledreject 用于将 Promise 对象的状态从 Pending 变为 Rejected

Promise 的基本用法

// 创建一个Promise实例
const promise = new Promise((resolve, reject) => {
  // 异步操作成功时调用resolve函数
  resolve('success');
  // 异步操作失败时调用reject函数
  reject('error');
});

// 处理Promise对象的状态改变
promise.then(value => {
  console.log(value); // "success"
}).catch(error => {
  console.log(error); // "error"
});

Promise 的链式调用

// 创建Promise实例
const promise1 = new Promise((resolve, reject) => {
  resolve('success1');
});


// 链式调用
promise1.then(value => {
  console.log(value); // "success1"
  return 'success2';
}).then(value => {
  console.log(value); // "success2"
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('success3');
    }, 1000);
  });
}).then(value => {
  console.log(value); // "success3"
}).catch(error => {
  console.log(error);
});

Promise 的错误处理

// 创建Promise实例
const promise = new Promise((resolve, reject) => {
  throw new Error('error');
});

// 处理Promise对象的状态改变
promise.then(value => {
  console.log(value);
}).catch(error => {
  console.log(error); // "error"
});

Promisefinally 方法

finally 方法的作用

finally 方法用于指定不管 Promise 实例最后状态如何,都会执行指定的回调函数。

finally 方法的用法

// 创建Promise实例
const promise = new Promise((resolve, reject) => {
  setTimeout(() => {
    resolve('success');
  }, 1000);
});

// 处理Promise对象的状态改变
promise.then(value => {
  console.log(value); // "success"
}).catch(error => {
  console.log(error);
}).finally(() => {
  console.log('finally');
});

Promise 的状态变化

const promise = new Promise((resolve, reject) => {
  // 异步操作成功时调用resolve函数
  resolve('success');
  // 异步操作失败时调用reject函数
  reject('error');
});

// 处理Promise对象的状态改变
promise.then(value => {
  console.log(value); // "success"
}).catch(error => {
  console.log(error); // "error"
});

Promise 的缺点

  • 无法取消 Promise,一旦新建就会立即执行,无法中途取消。
  • 如果不设置回调函数,Promise 内部抛出的错误,不会反应到外部。
  • 当处于 Pending 状态时,无法得知目前进展到哪一个阶段(刚刚开始还是即将完成)。
  • 如果不设置回调函数,Promise 对象会一直处于 Pending 状态,导致程序运行阻塞。

async/await

async/await 是什么?

async/awaitECMAScript 2017 引入的异步编程语法,它是 Promise 的语法糖。

async/await 让异步操作变得更加方便,让代码更简洁,更易读。

async/await 就是 Generator 函数和 Promise 的组合。

async/await的特点

  • 内置执行器。async/await 关键字会自动执行 Generator 函数,并返回一个 Promise 对象。
  • 更好的语义。async/await 更容易理解和编写。
  • 更广的适用性。async/await 适用于大多数异步操作,不仅仅局限于 Generator 函数。
  • 错误处理。async/await 可以捕获并处理 Promise 对象的错误。

async/await 的基本用法

async function hello() {
  return 'hello world';
}

hello().then(value => {
  console.log(value); // "hello world"
});

async/await 的链式调用

async function hello() {
  return 'hello';
}

async function world() {
  return 'world';
}

async function helloWorld() {
  const helloValue = await hello();
  const worldValue = await world();
  return `${helloValue} ${worldValue}`;
}


helloWorld().then(value => {
  console.log(value); // "hello world"
});

async/await 的错误处理

async function hello() {
  throw new Error('error');
}

hello().then(value => {
  console.log(value);
}).catch(error => {
  console.log(error); // "error"
});

async/awaitfinally 方法

async function hello() {
  return 'hello';
}

async function world() {
  return 'world';
}

async function helloWorld() {
  const helloValue = await hello();
  const worldValue = await world();
  return `${helloValue} ${worldValue}`;
}

helloWorld().then(value => {
  console.log(value); // "hello world"
}).finally(() => {
  console.log('finally');
});

async/await 的缺点

  • 无法取消 async/await,一旦开始就会执行,无法中途取消。
  • 无法获取函数执行的进度。
  • 错误处理不如 Promise 友好。
  • 调试不如 Generator 函数友好。

Generator 函数

什么是 Generator 函数?

Generator 函数是一种异步编程解决方案,它是一种特殊的函数,它返回一个可迭代对象(Iterator)。

Generator 函数是一个状态机,封装了多个内部状态。

Generator 函数运行后,返回一个遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。

Generator 函数可以暂停函数执行的位置,返回后续的执行结果。

Generator 函数可以让异步操作更加方便。

Generator 函数的特点

  • Generator 函数是一个状态机,封装了多个内部状态。
  • Generator 函数运行后,返回一个遍历器对象,可以依次遍历 Generator 函数内部的每一个状态。
  • Generator 函数可以暂停函数执行的位置,返回后续的执行结果。
  • Generator 函数可以暂停函数执行的位置,返回后续的执行结果。
  • Generator 函数可以方便地实现异步操作。

Generator 函数的基本用法

function* helloWorld() {
  yield 'hello';
  yield 'world';
}

const hw = helloWorld();

hw.next().value; // "hello"
hw.next().value; // "world"
hw.next().value; // undefined

Generator 函数的错误处理

function* helloWorld() {
  yield 'hello';
  throw new Error('error');
  yield 'world';
}

const hw = helloWorld();

hw.next().value; // "hello"
hw.next().value; // Uncaught Error: error

Generator 函数的 yield* 语句

yield* 语句可以将另一个 Generator 函数的执行结果,赋值给当前 Generator 函数的执行结果。

function* hello() {
  yield 'hello';
}

function* world() {
  yield 'world';
}

function* helloWorld() {
  yield* hello();
  yield* world();
}

const hw = helloWorld();

hw.next().value; // "hello"
hw.next().value; // "world"
hw.next().value; // undefined

Generator 函数的 return 语句

Generator 函数如果使用 return 语句,函数执行结束,且返回给定的值。

function* helloWorld() {
  yield 'hello';
  return 'world';
}

const hw = helloWorld();

hw.next().value; // "hello"
hw.next().value; // "world"
hw.next().value; // undefined

Generator 函数的 throw 语句

Generator 函数如果使用 throw 语句,函数会抛出错误,并中断执行。

function* helloWorld() {
  yield 'hello';
  throw new Error('error');
  yield 'world';
}

const hw = helloWorld();

hw.next().value; // "hello"
hw.next().value; // Uncaught Error: error
hw.next().value; // undefined

Generator 函数的 next 方法

Generator 函数的 next 方法可以手动控制 Generator 函数的执行。

function* helloWorld() {
  try {
    yield 'hello';
    yield 'world';
  } catch (e) {
    console.log(e);
  }
}

const hw = helloWorld();

hw.next().value; // "hello"
hw.next().value; // "world"
hw.next(); // { value: undefined, done: true }

Generator 函数的 for...of 循环

Generator 函数可以通过 for...of 循环来遍历执行。

function* helloWorld() {
  yield 'hello';
  yield 'world';
}

for (let value of helloWorld()) {
  console.log(value);
}
// "hello"
// "world"

Generator 函数的缺点

  • Generator 函数只能使用 for...of 循环来遍历,无法使用 next 方法来手动控制执行。
  • Generator 函数内部只能使用 yield 语句,不能使用 return 语句返回值。
  • Generator 函数内部的错误无法被捕获,只能在函数外部使用 try...catch 语句捕获。
  • Generator 函数没有自己的 this,所以无法用作类的构造函数。
  • Generator 函数的执行必须靠执行器,所以不适合在服务端使用。

async/awaitGenerator 函数的区别

async/awaitGenerator 函数的区别主要有以下几点:

  • async/awaitPromise 的语法糖,Generator 函数是 Iterator 的语法糖。
  • async/await 更简洁,更易读,内置执行器,更方便处理错误。
  • async/await 适用于大多数异步操作,不仅仅局限于 Generator 函数。
  • async/await 无法取消,Generator 函数可以取消。
  • async/await 无法获取函数执行的进度,Generator 函数可以获取函数执行的进度。
  • async/await 错误处理不如 Promise 友好,Generator 函数可以捕获并处理错误。
  • async/await 调试不如 Generator 函数友好,Generator 函数可以调试。
  • async/await 无法在服务端使用,Generator 函数可以在服务端使用。

async/awaitPromise 的区别

async/awaitPromise 的区别主要有以下几点:

  • async/awaitPromise 的语法糖。
  • async/await 更简洁,更易读,内置执行器,更方便处理错误。
  • async/await 适用于大多数异步操作,不仅仅局限于 Promise
  • async/await 无法取消,Promise 可以取消。
  • async/await 无法获取函数执行的进度,Promise 可以获取函数执行的进度。
  • async/await 错误处理不如 Promise 友好,Promise 可以捕获并处理错误。
  • async/await 调试不如 Promise 友好,Promise 可以调试。
  • async/await 无法在服务端使用,Promise 可以在服务端使用。

async/awaitGenerator 函数的选择

一般来说,如果需要处理多个异步操作,建议使用 async/await,因为它更简洁,更易读,而且内置执行器,更方便处理错误。

如果只需要处理单个异步操作,建议使用 Promise,因为它提供了统一的 API,各种异步操作都可以用同样的方法进行处理,并提供统一的接口。

如果需要处理多个异步操作,并且需要处理错误,建议使用 async/await,因为它更简洁,更易读,而且内置执行器,更方便处理错误。

Promiseasync/await的选择

一般来说,如果需要处理多个异步操作,建议使用 Promise,因为它提供了统一的 API,各种异步操作都可以用同样的方法进行处理,并提供统一的接口。

如果只需要处理单个异步操作,建议使用 async/await,因为它更简洁,更易读,而且内置执行器,更方便处理错误。

如果需要处理多个异步操作,并且需要处理错误,建议使用 Promise,因为它提供了统一的 API,各种异步操作都可以用同样的方法进行处理,并提供统一的接口。

  • 27
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值