The wind elegant 2022-08-06 08:29:09 阅读数:17
Today I would like to recommend a few to you JavaScript
Recommended practices for asynchronous code,Each scenario has a corresponding eslint
规则,You can choose to configure.
不建议将 async
函数传递给 new Promise
的构造函数.
//
new Promise(async (resolve, reject) => {});
//
new Promise((resolve, reject) => {});
首先,你在 Promise
in the constructor to use async
,Then pack Promise
Maybe it's not necessary.另外,如果 async
函数抛出了异常,新构造的 promise
instance does not reject
,Then this error cannot be caught.
Not recommended for use in the loop await
,Writing this way usually means that the program is underutilized JavaScript
的事件驱动.
//
for (const url of urls) {
const response = await fetch(url);
}
It is recommended to change these asynchronous tasks to concurrent execution,This can greatly improve the execution efficiency of the code.
//
const responses = [];
for (const url of urls) {
const response = fetch(url);
responses.push(response);
}
await Promise.all(responses);
不建议在 Promise
构造函数中返回值,Promise
The value returned in the constructor is not usable,and the return value will not affect Promise
的状态.
//
new Promise((resolve, reject) => {
return result;
});
The normal practice is to pass the return value to resolve
,If there is an error, pass it to reject
.
//
new Promise((resolve, reject) => {
resolve(result);
});
It is not recommended to put the assignment and operation await
组合使用,This can lead to race conditions.
看看下面的代码,你觉得 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
会打印 3 或 5,并不会打印 8,You can try it yourself in your browser.
The problem is with reading totalPosts
和更新 totalPosts
there is a time interval between.This results in a race condition,When the value is updated in a separate function call,Updates are not reflected in the current function scope.因此,Both functions will add their results to totalPosts
的初始值0.
The right way to avoid race conditions:
//
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);
防止回调地狱,Avoid a lot of deep nesting:
/* 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);
Callback hell makes code hard to read and maintain,It is recommended to refactor the callbacks as Promise
and use modern async/await
语法.
It is not necessary to write when returning asynchronous results await
,If you are waiting for a Promise
,and then immediately return to it,这可能是不必要的.
//
async () => {
return await getUser(userId);
}
从一个 async
All values returned by the function are contained in a Promise
中,you can just return this Promise
.
//
async () => {
return getUser(userId);
}
当然,也有个例外,如果外面有 try...catch
包裹,删除 await
Can't catch exception,在这种情况下,It is recommended to clarify the intention,assign the result to a variable on a different row.
//
async () => {
try {
return await getUser(userId);
} catch (error) {
// Handle getUser error
}
}
//
async () => {
try {
const user = await getUser(userId);
return user;
} catch (error) {
// Handle getUser error
}
}
建议在 reject Promise
时强制使用 Error
对象,This makes it easier to trace the error stack.
//
Promise.reject('An error occurred');
//
Promise.reject(new Error('An error occurred'));
强制在 Node.js
In the asynchronous callback of exception handling.
//
function callback(err, data) {
console.log(data);
}
//
function callback(err, data) {
if (err) {
console.log(err);
return;
}
console.log(data);
}
在 Node.js
中,Usually the exception is passed as the first parameter to the callback function.Forgetting to handle these exceptions can lead to unpredictable problems with your application.
If the first parameter of the function is named
err
will trigger this rule,你也可以去.eslintrc
Custom exception parameter name in the file.
Not recommended where asynchronous alternatives exist Node.js
核心 API
Synchronous method used in.
//
const file = fs.readFileSync(path);
//
const file = await fs.readFile(path);
在Node.js
中对 I/O
Operation using a synchronous method blocks the event loop.大多数场景下,执行 I/O
Using async methods when operating is a better choice.
不建议 await
非 Promise
function or value.
//
function getValue() {
return someValue;
}
await getValue();
//
async function getValue() {
return someValue;
}
await getValue();
建议 Promise
Additional code for exception handling.
//
myPromise()
.then(() => {});
//
myPromise()
.then(() => {})
.catch(() => {});
form a good habit,Always do exception handling!
不建议将 Promise
pass to places where they are not intended to be processed,例如 if 条件.
//
if (getUserFromDB()) {}
//
if (await getUserFromDB()) {}
It is more recommended to extract a variable to improve the readability of the code.
//
const user = await getUserFromDB();
if (user) {}
版权声明:本文为[The wind elegant]所创,转载请带上原文链接,感谢。 https://qdmana.com/2022/218/202208060818127811.html