我正在嘗試將接收到的資料作為 JSON 保存在 DB 中。但是我的方法是不必要的耗時,所以我寫了這個問題。
這是我的代碼:
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]。我怎樣才能并行運行它們?
uj5u.com熱心網友回復:
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;
}
uj5u.com熱心網友回復:
將創建用戶和相關元資料的程序包裝到一個函式中,例如
async function createUserAndMeta(user) {
console.log(user);
const usersId = await createUser(user);
const result = [];
for (const item of user.items) {
const fn2Return = await createUserMeta(usersId, item.name);
result.push(fn2Return);
}
return result;
}
然后用于map將所有用戶映射到承諾并Promise.all()等待他們:
async function asyncCall() {
const results = await Promise.all(data.map(createUserAndMeta));
const result = results.flat(); // flatten array of arrays
console.log(result);
}
請注意,如果您有很多data,這將導致所有請求并行完成(例如,對于 50 個用戶,它會嘗試進行 50 個并行createUser呼叫)。要將并發限制為一次例如 5 個,您可能需要使用例如p-queuemodule。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/344602.html
標籤:javascript 异步 异步等待
