前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >JavaScript异步编程:Promise、async&await与Generator

JavaScript异步编程:Promise、async&await与Generator

原创
作者头像
iwhao
发布2024-07-04 23:30:51
1281
发布2024-07-04 23:30:51

Promise、async/await与Generator 是什么?它们有什么区别?

Promise 是 JavaScript 中用于处理异步操作的一种解决方案,它提供了一种更简洁、更清晰的方式来处理异步操作的结果。Promise 有三种状态:pending(进行中)、fulfilled(已完成,成功)和 rejected(已完成,失败)。Promise 的核心概念是链式调用,通过 .then() 方法处理成功(fulfilled)的结果,或者通过 .catch() 方法处理失败(rejected)的结果。

Async/Await

Async/await 是基于 Promise 的高级异步编程语法,它使得异步代码看起来更像是同步代码。使用 async 关键字定义一个函数,该函数内部可以使用 await 关键字等待 Promise 的结果。当遇到 await 时,函数会暂停执行,直到 Promise 被解析成功或失败。成功时返回 Promise 的值,失败时返回 Promise 的错误。这使得代码更易于阅读和理解,因为不需要显式地处理回调函数。

Generator

Generator函数是ES6引入的一种特殊函数,允许你编写出可以暂停执行并稍后继续执行的函数。Generator 函数使用 function* 关键字定义,内部使用 yield 关键字来暂停执行并返回一个值。当调用 Generator 函数时,它会返回一个迭代器对象,这个迭代器对象可以使用 next() 方法来继续执行 Generator 函数,直到所有 yield 表达式执行完毕或遇到 return 语句。

实战用法

Promise

Promise的基本用法

代码语言:js
复制
const fetchData = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('Data fetched successfully');
    }, 1000);
  });
};

fetchData()
  .then(data => {
    console.log(data); 
  })
  .catch(error => {
    console.error(error);
  });

Promise链

Promise链允许 按顺序执行多个异步操作:

代码语言:js
复制
const fetchData = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('Data fetched successfully');
    }, 1000);
  });
};

const processData = data => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(`Processed ${data}`);
    }, 1000);
  });
};

fetchData()
  .then(data => processData(data))
  .then(processedData => {
    console.log(processedData);  successfully'
  })
  .catch(error => {
    console.error(error);
  });

Promise并发执行

代码语言:js
复制
const fetchData1 = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('Data1 fetched successfully');
    }, 1000);
  });
};

const fetchData2 = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('Data2 fetched successfully');
    }, 1000);
  });
};
const main = async () => {
  try {
    const [data1, data2] = await Promise.all([fetchData1(), fetchData2()]);
    console.log(data1, data2); // 'Data1 fetched successfully' 'Data2 fetched successfully'
  } catch (error) {
    console.error(error);
  }
};

async/await

async/await的基本用法

代码语言:js
复制
const fetchData = () => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('Data fetched successfully');
    }, 1000);
  });
};

const processData = data => {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve(`Processed ${data}`);
    }, 1000);
  });
};

const main = async () => {
  try {
    const data = await fetchData();
    const processedData = await processData(data);
    console.log(processedData); // 'Processed Data fetched successfully'
  } catch (error) {
    console.error(error);
  }
};

Generator

Generator的基本用法

  • 注:yield 是Generator函数中的一个关键字,它的作用是在每次函数暂停执行时返回一个值。yield表达式后面可以跟一个表达式,该表达式的值就是每次调用next()方法时返回的值。
  • 注:function* () 定义的是一个生成器函数(Generator Function)
代码语言:js
复制
function* fetchDataGenerator() {
  yield new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('Data fetched successfully');
    }, 1000);
  });
}

const gen = fetchDataGenerator();
const promise = gen.next().value;

promise.then(data => {
  console.log(data); // 'Data fetched successfully'
});

结合Promise和Generator

代码语言:js
复制
function run(generatorFn) {
  const gen = generatorFn();

  function handle(result) {
    if (result.done) return Promise.resolve(result.value);

    return Promise.resolve(result.value)
      .then(res => handle(gen.next(res)))
      .catch(err => gen.throw(err));
  }

  return handle(gen.next());
}

function* fetchDataGenerator() {
  const data = yield new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('Data fetched successfully');
    }, 1000);
  });

  console.log(data); // 'Data fetched successfully'
}

run(fetchDataGenerator);

至于在实际开发中应该怎么用,可以考虑实际场景来选择,因为这三种方法各有的优缺点,下面总结一下,可以根据每种方法的特点择优选择使用。

  • Promise提供了一种标准化的方式来处理异步操作的结果。可以方便地进行链式操作和组合多个异步操作。但容易出现回调地狱,导致代码结构复杂
  • async/await呢,就是基于 Promise 的语法糖,它允许你以同步的方式编写异步代码,极大地提高了异步代码的可读性和可维护性。错误处理更简单和直观。但就是不支持在普通函数中使用(函数前要加async标识),
  • Generator 则是用于创建迭代器的工具,允许在函数执行过程中暂停和恢复执行,适用于需要分批处理大量数据或需要在多个步骤间暂停执行的场景。且不如 async/await 那样直观,而且语法相对复杂,理解和使用成本较高。错误处理不够直观和简洁。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Promise、async/await与Generator 是什么?它们有什么区别?
  • 实战用法
    • Promise
      • Promise的基本用法
      • Promise链
      • Promise并发执行
    • async/await
      • async/await的基本用法
    • Generator
      • Generator的基本用法
      • 结合Promise和Generator
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档