您现在的位置是:亿华云 > IT科技
14条ESLint规则让你的异步代码更优雅
亿华云2025-10-02 18:51:07【IT科技】8人已围观
简介在 JavaScript 编写调试异步代码时,ESlint 可以帮我们及时发现一些错误。即使没有在项目中用到这些规则,理解它们的含义也将有助于帮助我们更好地理解和编写异步代码。异
在 JavaScript 编写调试异步代码时,则让ESlint 可以帮我们及时发现一些错误。步代即使没有在项目中用到这些规则,码更理解它们的优雅含义也将有助于帮助我们更好地理解和编写异步代码。
异步代码的则让ESLint规则
以下规则默认随ESLint一起提供,可以在 .eslintrc 配置文件中启用它们。步代
此规则不允许将 async 函数传递给 new Promise 构造函数。码更
// ❌
new Promise(async (resolve,优雅 reject) => { });
// ✅
new Promise((resolve, reject) => { });虽然将异步函数传递给 Promise 构造函数在技术上是没有问题的,但由于以下两个原因,则让这样做通常都是步代错误的:
如果异步函数抛出错误,错误将会丢失而不会被新构造的码更 Promise 拒绝;如果 await 在构造函数内部使用,包装 Promise 是优雅不必要的,可以将其删除。则让2. no-await-in-loop此规则不允许在循环内使用 await。步代
当对可迭代的码更每个元素执行操作并等待异步任务时,通常表明程序没有充分利用 JavaScript 的事件驱动架构。通过并行执行这些任务,可以大大提高代码的效率。服务器租用
// ❌
for (const url of urls) {
const response = await fetch(url);
}
// ✅
const responses = [];
for (const url of urls) {
const response = fetch(url);
responses.push(response);
}
await Promise.all(responses);当确实需要按照顺序执行任务的情况下,建议使用内联注释禁用此规则:
// eslint-disable-line no-await-in-loop。3. no-promise-executor-return此规则不允许在 Promise 构造函数中返回值。
// ❌
new Promise((resolve, reject) => {
return result;
});
// ✅
new Promise((resolve, reject) => {
resolve(result);
});在 Promise 构造函数中返回的值不能被使用并且不会以任何方式影响 Promise。应该将值传递给 resolve,如果发生错误,则调用 reject 并显示错误。
此规则不会阻止在 Promise 构造函数的嵌套回调中返回值。始终确保使用 resolve 或 reject 来完成 Promise。
4. require-atomic-updates此规则不允许由于 await 或 yield 的使用而可能导致出现竞态条件的赋值。
来看下面的例子,totalPosts 的最终值是多少?
// ❌
let totalPosts = 0;
async function getPosts(userId) {
const users = [{ id: 1, posts: 5 }, { id: 2, posts: 3 }];
await sleep(Math.random() * 1000);
return users.find((user) => user.id === userId).posts;
}
async function addPosts(userId) {
totalPosts += await getPosts(userId);
}
await Promise.all([addPosts(1), addPosts(2)]);
console.log(Post count:, totalPosts);这里 totalPosts 不会打印 8,而会打印 5 和 3。问题就在于读取和更新 totalPosts 之间存在时间间隔。这会导致竞态条件,使得在单独的函数调用中更新值时,更新不会反映在当前函数范围中。因此,这两个函数都将它们的结果添加到初始值为 0 的云南idc服务商 totalPosts 中。
为了避免这种竞态条件,应该确保在更新变量的同时读取变量:
// ✅
let totalPosts = 0;
async function getPosts(userId) {
const users = [{ id: 1, posts: 5 }, { id: 2, posts: 3 }];
await sleep(Math.random() * 1000);
return users.find((user) => user.id === userId).posts;
}
async function addPosts(userId) {
const posts = await getPosts(userId);
totalPosts += posts; // variable is read and immediately updated
}
await Promise.all([addPosts(1), addPosts(2)]);
console.log(Post count:, totalPosts);5. max-nested-callbacks此规则会强制回调的最大嵌套深度。换句话说,这条规则可以防止回调地狱。
/* eslint max-nested-callbacks: ["error", 3] */
// ❌
async1((err, result1) => {
async2(result1, (err, result2) => {
async3(result2, (err, result3) => {
async4(result3, (err, result4) => {
console.log(result4);
});
});
});
});
// ✅
const result1 = await asyncPromise1();
const result2 = await asyncPromise2(result1);
const result3 = await asyncPromise3(result2);
const result4 = await asyncPromise4(result3);
console.log(result4);深层的嵌套使代码难以阅读和维护。在编写 JavaScript 异步代码时,可以将回调重构为 Promise 并使用 async/await 语法。
6. no-return-await此规则不允许返回不必要的 await。
// ❌
async () => {
return await getUser(userId);
}
// ✅
async () => {
return getUser(userId);
}等待一个 Promise 并立即返回它是没有必要的,因为从异步函数返回的所有值都包含在一个 Promise 中。因此,可以直接返回 Promise。
此规则的一个例外情况就是当有 try...catch 语句时, 删除 await 关键字将导致不会捕获 Promise 拒绝的原因。在这种情况下,建议将结果分配给变量以明确意图。
//很赞哦!(965)