【问题标题】:Child functions and async await子函数和异步等待
【发布时间】:2019-06-13 22:21:33
【问题描述】:

在我的一个 API 端点中,我从 Web 获取一个 json 资源 (1) 并对其进行编辑以满足我的需要。在树的“最低”或“最深”部分,我试图获取另一个资源并将其添加到最终的 json 对象中。我对 async/await 比较陌生,但我正在尝试摆脱“旧”Promises,因为我看到了使用 async/await 的优势(或收益)。

(1)中的对象看起来像;

const json = {
  date,
  time,
  trips: [{
    name,
    legs: [{
        id
      },
      {
        id
      }
    ]
  }]
};

这是我“重新格式化”和更改 json 对象的方法;

{
  date,
  time,
  trips: json.trips.map(trip => formatTrip(trip))
};

function formatTrip(trip) {
  return {
    name,
    legs: trip.legs.map(leg => formatLeg(leg))
  };
};

async function formatLeg(leg) {
  const data = await fetch();

  return {
    id,
    data
  };
};

问题在于,在我“重新格式化/编辑”原始 json 以查看我想要的方式(并运行所有 format... 函数)之后,legs 对象为空 {}

我认为这可能是由于 async/await 承诺没有完成。我还读到,如果子函数使用 async/await,则所有高级函数也必须使用 async/await。

为什么?我怎样才能重写我的代码才能工作并看起来不错?谢谢!

编辑:

我根据 Randy 的回答更新了我的代码。 getLegStops(leg) 仍然未定义/为空。

function formatLeg(leg) {
  return {
    other,
    stops: getLegStops(leg)
  };
};

function getLegStops(leg) {
  Promise.all(getLegStopRequests(leg)).then(([r1, r2]) => {
    /* do stuff here */
    return [ /* with data */ ];
  });
};

function getLegStopRequests(leg) {
  return [ url1, url2 ].map(async url => await axios.request({ url }));
};

【问题讨论】:

    标签: javascript function async-await axios


    【解决方案1】:

    有两件事让你想要嵌套这些 Promise:

    1. 考虑回调然后是 Promise 的旧方法
    2. 相信软件过程必须匹配数据结构

    如果我理解正确,您似乎只需要处理一次 Promise。

    像这样:

    async function getLegs(){
     return trip.legs.map(async leg => await fetch(...)); // produces an array of Promises
    }
    
    const legs = Promise.all(getLegs());
    
    function formatLegs(legs) {
       // do something with array of legs
    };
    
    function formatTrip(){
       //format final output
    }

    编辑:根据您在下面的评论,这个 sn-p 代表我已经展示的内容以及您的目标应该是什么样的。请仔细检查您的代码。

    const arr = [1, 2, 3, ];
    
    const arrPromises = arr.map(async v => await new Promise((res) => res(v)));
    const finalPromise = Promise.all(arrPromises);
    console.log(finalPromise.then(console.log));

    【讨论】:

    • 感谢您的回复!我试过你说的,但不幸的是它没有用。此外,在您的答案中 getLegs 之前进行异步会产生错误:# 不可迭代。我用更多代码更新了我原来的问题!
    • 请查看编辑。毫无疑问,您编写的代码不正确。
    • 好吧,我刚刚注意到您正在使用 Axios。 Axios 就像现代的 jQuery - 你要么全力以赴,要么不参与。将标准 JavaScript 语法与 Axios 混合是一个坏主意。在问题中识别 Axios,你会得到一些 Axios 的喜爱。但是这个简单的代码不需要它。回到你身边。
    猜你喜欢
    • 2020-08-01
    • 2023-03-13
    • 2017-04-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-28
    • 1970-01-01
    相关资源
    最近更新 更多