首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用forEach和axios的异步/等待

使用forEach和axios的异步/等待
EN

Stack Overflow用户
提问于 2018-10-12 23:07:59
回答 2查看 11.5K关注 0票数 0

我被困在一个问题上我需要你的帮助。我需要使用和API自动注册服务器在一个软件名为舵。为了达到我的目标,我必须使用2 http请求:

  1. (获取)获取状态挂起的所有服务器
  2. (张贴)注册我的服务器

我的第一个请求处理得很好,但我不知道如何处理第二个请求。

在这里,我的代码(/src/控制器/Registration.js):

代码语言:javascript
复制
async function index(req, res) {
  // Check parameter
  if (!req.body.hostname) {
    return res.status(422).json({ result: 'error', message: 'Missing hostname parameter' });
  }

  try {
    const pendingNodes = await axios.get(`${config.rudderURL}/rudder/api/latest/nodes/pending?include=minimal`, { headers });
    Object.keys(pendingNodes.data.data.nodes).forEach((key) => {
      // Search in all pending machine if our node is present
      const node = pendingNodes.data.data.nodes[key];
      if (req.body.hostname === node.hostname) {
        // Registration
        const response = async axios.get(`${config.rudderURL}/rudder/api/nodes/pending/${node.id}`, { headers });
        // console.log(response);
        return res.status(200).json({ result: 'success', message: 'Host added to rudder' });
      }
    });
  } catch (err) {
    return res.status(500).json({ result: 'error', message: `${err}` });
  }

  return res.status(500).json({ result: 'error', message: 'Host not found' });
}

如您所见,我使用Object.keys(...).forEach(...)来迭代第一个请求的结果。

请注意,第一个请求的答复如下:

代码语言:javascript
复制
{
    "action": "listPendingNodes",
    "result": "success",
    "data": {
        "nodes": [
            {
                "id": "f05f2bde-5416-189c-919c-954acc63dce7",
                "hostname": "foo",
                "status": "pending"
            },
            {
                "id": "b7f597ef-2b46-4283-bf70-d5e8cd84ba86",
                "hostname": "bar",
                "status": "pending"
            }
        ]
    }
}

我需要迭代这个输出,并将每个nodes的主机名字符串与我的输入(来自脚本或postman的简单post请求)进行比较。

如果2字符串等于,我的第二个请求将启动,并且必须在服务器中注册我的主机(请求在这里简化了,但您得到了)。

我的问题是,我找不到办法使第二个请求生效。我尝试不同的解决方案,并在一些论坛和网站上看到,它是复杂的工作循环和异步/等待在同一时间,但你有一个想法吗?

当我尝试我的代码时,我会收到一条错误消息:

错误ERR_HTTP_HEADERS_SENT:无法在标头发送到客户端后设置它们

据我所知,forEach(...)不等待我的第二个请求结果。因此,return res.status(200).json({ result: 'success', message: 'Host added to rudder' });被称为另一个,可能是return res.status(500).json({ result: 'error', message: 'Host not found' });。我说得对吗?

我是说,真正的困难(或者不是?)是Object.keys(...).forEach(...)。也许有一种简单的方法可以不使用这个函数,而使用另一个函数?或者重构我的代码?

致以问候。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-10-13 03:30:06

你所犯的错误

错误ERR_HTTP_HEADERS_SENT:无法在标头发送到客户端后设置它们

这是因为您多次调用res.status(200) (将其放入forEach循环中)。必须只执行一次此响应。

我一直在深入研究这个解决方案,并开始使用reducemapPromise.all

代码语言:javascript
复制
async function index(req, res) {
  // Check parameter
  ...

  try {
    const pendingNodes = await axios.get(`${config.rudderURL}/rudder/api/latest/nodes/pending?include=minimal`, { headers });

    // we get node ids in array with hostname is matched with req.body.hostname
    const nodeIdsToRegister = pendingNodes.data.data.nodes.reduce((result, node) => {
      return req.body.hostname === node.hostname ? [...result, node.id] : result;
    }, [])

    // use `Promise.all` to register all node Ids we got previously
    const registers = await Promise.all(nodeIdsToRegister.map(nodeId => axios.get(`${config.rudderURL}/rudder/api/nodes/pending/${node.id}`, { headers })));

    res.status(200).json({ result: 'success', message: 'Host added to rudder' });

  } catch (err) {
    return res.status(500).json({ result: 'error', message: `${err}` });
  }

  return res.status(500).json({ result: 'error', message: 'Host not found' });
}
票数 2
EN

Stack Overflow用户

发布于 2018-10-13 03:11:06

异步等待在forEach循环中不工作。将forEach转换为for循环。差不多是这样的:

代码语言:javascript
复制
let nodes = Object.keys(pendingNodes.data.data.nodes;
for (let i = 0; i < nodes.length; i++) {
    // Perform asynchronous actions and await them, it will work
    ...
}

在这里阅读更多信息:Using async/await with a forEach loop

另外,一个函数是异步的,您可以在其中等待多个语句。您已经在axios.get前面编写了异步代码,它基本上是返回承诺的。你应该等着呢。

将以下内容从

代码语言:javascript
复制
const response = async axios.get(`${config.rudderURL}/rudder/api/nodes/pending/${node.id}`, { headers });

代码语言:javascript
复制
const response = await axios.get(`${config.rudderURL}/rudder/api/nodes/pending/${node.id}`, { headers });
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52788046

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档