在 ES2019 中,JavaScript 引入了一个新的静态方法 .fromEntries(),它可以将一个由键值组成的数组转换为一个对象。这使得我们在开发过程中能够更轻松地处理数据。
不过,从一些实践中发现,在异步状态下使用 .fromEntries() 有一些特殊的需求。
异步状态下的需求
在异步状态下常常需要将后端返回的数据转换成 JavaScript 对象,这时 .fromEntries() 是一个非常好用的方法。比如,可以将一个由后端返回的数组转换成一个以数组元素为键的对象。
// www.javascriptcn.com code example
// 假设后端返回数据如下:
const data = [
{ key: 'name', value: 'Tom' },
{ key: 'age', value: 18 },
{ key: 'gender', value: 'male' },
];
// 使用 .fromEntries() 方法转换成对象
const obj = Object.fromEntries(data.map((item) => [item.key, item.value]));
console.log(obj); // { name: 'Tom', age: 18, gender: 'male' }不过,如果你尝试将上述代码放在一个异步回调中,你会发现代码不能正常执行。
fetch('/api/data')
.then((response) => response.json())
.then((data) => {
const obj = Object.fromEntries(data.map((item) => [item.key, item.value]));
console.log(obj); // 无输出
});原因是,异步回调函数的执行顺序是不确定的,如果异步操作没完成,同步代码会继续执行,导致 .fromEntries() 方法执行时数组为空。
为了解决这个问题,我们需要改变代码的执行顺序,等到异步操作结束后再进行转换。下面我们将详细讲解如何在异步状态下使用 .fromEntries()。
适应异步状态的解决方案
第一种解决方案是使用 async/await 关键字,在异步函数中等待异步操作完成后再转换数据。
async function fetchData() {
const response = await fetch('/api/data');
const data = await response.json();
const obj = Object.fromEntries(data.map((item) => [item.key, item.value]));
console.log(obj);
}
fetchData();第二种解决方案是使用原生的 Promise 对象,将 .fromEntries() 这一行转换成一个返回 Promise 对象的异步函数,并在异步回调中等待异步操作完成后再调用函数。
// www.javascriptcn.com code example
// 定义异步函数
function fromEntriesPromise(data) {
return new Promise((resolve, reject) => {
const obj = Object.fromEntries(data);
resolve(obj);
});
}
// 异步回调中使用
fetch('/api/data')
.then((response) => response.json())
.then((data) => fromEntriesPromise(data.map((item) => [item.key, item.value])))
.then((obj) => console.log(obj))
.catch((error) => console.error(error));深度和学习以及指导意义
.fromEntries() 方法在异步状态下需要特别注意,由于异步操作的不确定性,我们需要手动控制数据转换的执行顺序,使其在异步操作完成后再执行转换。
掌握 .fromEntries() 方法在异步状态下的用法,有助于我们更好地理解异步回调函数的执行顺序,加深对 JavaScript 异步编程的理解。
同时,这种需求还表明了 JavaScript 在异步编程上的复杂性和迫切性。在未来的开发中,我们应该更加注意异步编程的规范,避免遇到类似问题的困扰,并保证程序的健壮性和可靠性。
示例代码
你可以在我的 GitHub 仓库中找到示例代码:https://github.com/jinghongkuixia/async-fromEntries。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/67d78db6a941bf7134d85bf7