我需要在await
函数调用结束时循环并等待修改后的结果。
什么是等待所有执行的最佳选择,只有在完成循环后,返回结果?
try {
for await (var [i, object] of tablesArchive.data.entries()) {
if (Object.keys(object).length === 0) {
continue;
}
// Busca IDs de relacoes existentes
await this.getIdByRalations(tablesArchive, object, async (newObject) => {
where = { [whereByProperty]: newObject[whereByProperty] };
// Atualiza ou cria o registro na base de dados
const registro = await this.upsertWithWhere(app, tablesArchive.modelName, where, newObject);
tablesArchive.data[i].id = registro.id;
});
}
} finally {
console.log('FINALLY ');
return tablesArchive.data;
}
在上面的例子中,我需要修改tablesArchive.data
对象,并且只有在遍历所有索引之后,才能更新信息。我希望通过所有修改来调用返回。
你最后并没有严格要求。你使用await已经导致代码“等待”,直到它完成执行最后2个语句。
最后可能需要的具体情况是,如果你的try
阻止你可能会遇到异常并且你想确保finally块中的代码总是被执行,异常与否。
我不认为这是默认情况下你需要添加的东西,只要有可能抛出异常。问题是,如果发生异常,你想做什么?我认为处理这个问题的默认方法是让异常抛出并回滚堆栈,并且只能被第一件可以用它做的事情抓住。
有一个特定的情况,我总是想要一个finally块,当我在连接中做数据库相关的东西时我需要释放连接是否抛出异常:
try {
const conn = pool.getConnection();
await conn.query('...');
await conn.query('...');
} finally {
// Always release, error or not
conn.release();
}
上面的代码块在我的源代码中相当普遍,但这只是因为我想要一个特定的东西,无论是否发生异常。
您可以将try / catch放在for循环中并在catch块中,只需记录错误。然后它将继续运行,你可以在for循环之后放置你的return语句。
for (var [i, object] of tablesArchive.data.entries()) {
try {
if (Object.keys(object).length === 0) {
continue;
}
// Busca IDs de relacoes existentes
await this.getIdByRalations(tablesArchive, object, async (newObject) => {
where = { [whereByProperty]: newObject[whereByProperty] };
// Atualiza ou cria o registro na base de dados
const registro = await this.upsertWithWhere(app, tablesArchive.modelName, where, newObject);
tablesArchive.data[i].id = registro.id;
});
} catch (e) {
console.log(e);
}
}
return tablesArchive.data;
这里看一下Promise.all() API。
简短摘要:你向Promises提供了一个Promise.all()数组,并等到这个数组中的所有Promise都完成了。
用你的例子,我会这样做:
var promises = []
for await (var [i, object] of tablesArchive.data.entries()) {
if (Object.keys(object).length === 0) {
continue;
}
// I changed this line here
// just push every async function to the promises array
promises.push(this.getIdByRalations(tablesArchive, object, async (newObject) => {
where = { [whereByProperty]: newObject[whereByProperty] };
// Atualiza ou cria o registro na base de dados
const registro = await this.upsertWithWhere(app, tablesArchive.modelName, where, newObject);
tablesArchive.data[i].id = registro.id;
}));
}
return await Promise.all(promises).then(() => {
console.log('All promises are finished')
return tablesArchive.data
}).catch(err => {
console.error('Error occured in Promises.all: ' + err)
}).finally(() => {
console.log('All promises Finished')
})