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)
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 那样直观,而且语法相对复杂,理解和使用成本较高。错误处理不够直观和简洁。