javascript - 对 json 数据使用异步的最佳实践
问题描述
我正在尝试将接收到的数据保存为数据库中的 JSON。但是我的方法不必要地耗时,所以我写了这个问题。
这是我的代码:
const data = [{
id: 1,
name: 'foo',
items: [{
name: 'foo-1'
}, {
name: 'foo-2'
}]
}, {
id: 2,
name: 'bar',
items: [{
name: 'bar-1'
}, {
name: 'bar-2'
}]
}]
const createUser = (data) => {
console.log('start create user:', data)
return new Promise(resolve => {
setTimeout(() => {
console.log('create user: ', data.name)
resolve(data.id);
}, 2000);
});
}
const createUserMeta = (id, name) => {
console.log('start create user meta:', name)
return new Promise(resolve => {
setTimeout(() => {
console.log('create user meta: ', id, name)
resolve(`set ${id}: ${name}`)
}, 3000)
})
}
// Logic
async function asyncCall() {
const result = []
console.log('calling')
for (const i of data) {
console.log(i)
const usersId = await createUser(i)
for (const item of i.items) {
const fn2Return = await createUserMeta(usersId, item.name)
result.push(fn2Return)
}
}
console.log(result)
}
asyncCall();
结果是:
calling
{ id: 1, name: 'foo', items: [ { name: 'foo-1' }, { name: 'foo-2' } ] }
start create user: { id: 1, name: 'foo', items: [ { name: 'foo-1' }, { name: 'foo-2' } ] }
// wait 2 sec
create user: foo
start create user meta: foo-1
// wait 3 sec
create user meta: 1 foo-1
start create user meta: foo-2
// wait 3 sec
create user meta: 1 foo-2
{ id: 2, name: 'bar', items: [ { name: 'bar-1' }, { name: 'bar-2' } ] }
start create user: { id: 2, name: 'bar', items: [ { name: 'bar-1' }, { name: 'bar-2' } ] }
// wait 2 sec
create user: bar
start create user meta: bar-1
// wait 3 sec
create user meta: 2 bar-1
start create user meta: bar-2
// wait 3 sec
create user meta: 2 bar-2
[ 'set 1: foo-1', 'set 1: foo-2', 'set 2: bar-1', 'set 2: bar-2' ]
createUserMeta 应该等待 createUser 在启动之前退出。但无需等待 data[0] 完成即可保存 data[1]。如何并行运行它们?
解决方案
async function createUser(data) {
const pk = await insertUser(data.id, data.name);
const result = await Promise.all(data.items.map(createUserMeta);
return {pk, result};
}
async function asyncCall() {
const result = await Promise.all(data.map(createUser));
return result;
}
推荐阅读
- laravel - 如何在 Laravel 中使用带局部变量的 where 子句而不传递参数
- java - 由于向数据库添加数据而导致应用程序崩溃
- delphi - 使用 VCL 样式隐藏 MDI 表单中的滚动条
- eclipse - 为什么 Jenkins 会更改我的工作空间路径?
- laravel - 当单击外部 div 时,vuejs 停止传播单击
- javascript - useEffect 缺少依赖项(使用 useContext 而不是 useState 时)
- javascript - 如何获取 DOM 中渲染的 Vue 组件的数量?
- python - Python:“myvar = 1000”有什么作用?
- tcl - 在 tcl 中打开 gnome-terminal 并运行脚本
- php - 有人知道如何根据字符串名称更改颜色吗?