如何按条件顺序调用异步函数并避免嵌套?Promise实现咨询
异步函数顺序执行与消除嵌套实现方案
我有一个根据条件处理数据的函数,在else分支中需要依次调用两个异步函数(先执行dev环境的查询,再执行prod环境的查询)。目前代码存在嵌套结构,希望改成无嵌套的写法,已知可以通过Promise实现,但不清楚具体操作方式。
当前代码:
result.data.table_fields.forEach((d) => { if (d.type != "connected_field") { // do something } else { getAllTables({ query: tables(dev_id) }).then((res) => { if (d.label in res) { // do something } else { getAllTables({ query: tables(prod_org) }).then((prod) => { if (d.label in prod) { //do something } else console.log(`${d.label} DOES NOT EXIST}`); }); } }); } });
方案1:Promise链式调用
利用Promise的链式调用特性,避免嵌套。在第一个then中,如果dev环境未找到数据,返回第二个getAllTables的Promise,后续用另一个then处理prod环境的结果:
result.data.table_fields.forEach((d) => { if (d.type !== "connected_field") { // do something } else { getAllTables({ query: tables(dev_id) }) .then((res) => { if (d.label in res) { // do something return Promise.resolve(); // 返回已完成的Promise,跳过后续prod查询 } // dev环境未找到,执行prod查询并返回其Promise return getAllTables({ query: tables(prod_org) }); }) .then((prod) => { // 这里的prod只有当dev未找到时才存在 if (prod && d.label in prod) { // do something } else if (prod) { // 确保是prod查询后的结果且未找到 console.log(`${d.label} DOES NOT EXIST`); } }) .catch((err) => { // 处理异步请求的错误 console.error('查询出错:', err); }); } });
方案2:async/await(更直观)
使用async/await可以让异步代码看起来像同步代码,彻底消除嵌套。注意:forEach无法正确处理异步函数,建议改用for...of循环:
// 包裹在async函数中 (async () => { for (const d of result.data.table_fields) { if (d.type !== "connected_field") { // do something continue; } try { const res = await getAllTables({ query: tables(dev_id) }); if (d.label in res) { // do something continue; } // dev未找到,查询prod const prod = await getAllTables({ query: tables(prod_org) }); if (d.label in prod) { // do something } else { console.log(`${d.label} DOES NOT EXIST`); } } catch (err) { console.error('查询出错:', err); } } })();
说明
- 两种方案都实现了先dev后prod的顺序执行,且无嵌套结构
async/await写法可读性更高,是当前推荐的异步代码写法- 新增了
catch块处理异步请求可能出现的错误,避免遗漏异常
内容的提问来源于stack exchange,提问作者nb_nb_nb
相关产品推荐
相关产品推荐

