除非结合使用await和then,否则3个节点获取POST调用的序列会失败

问题描述 投票:0回答:1

在 javascript 中,我运行以下 3 个 fetch POST 请求:

测试.js

fetch(endpoint, {
  method: "POST",
  headers: {
    Authorization: "Bearer " + token,
    "Content-Type": "application/json-patch+json",
    "accept": "application/json"  
  },
  body: b1
})
 .then((response) => {
  console.log(response.status)
  return response.json()
})
.then(data => {
  console.log(data);
})
.catch(error => {
  console.error('CREATE Error:', error);
});


fetch(endpoint, {
  method: "POST",
  headers: {
    Authorization: "Bearer " + token,
    "Content-Type": "application/json-patch+json",
    "accept": "application/json"  
  },
  body: b2
})
 .then((response) => {
  console.log(response.status)
  return response.json()
})
.then(data => {
  console.log(data);
})
.catch(error => {
  console.error('CREATE Error:', error);
});


fetch(endpoint, {
  method: "POST",
  headers: {
    Authorization: "Bearer " + token,
    "Content-Type": "application/json-patch+json",
    "accept": "application/json"  
  },
  body: b3
})
 .then((response) => {
  console.log(response.status)
  return response.json()
})
.then(data => {
  console.log(data);
})
.catch(error => {
  console.error('CREATE Error:', error);
});

但它会随机因一两个请求而失败,例如:

❯ node test.js
500
{
  type: 'https://httpstatuses.com/500',
  title: 'Internal Server Error',
  status: 500,
  detail: ''
}
500
{
  type: 'https://httpstatuses.com/500',
  title: 'Internal Server Error',
  status: 500,
  detail: ''
}
200
{
  status: 'succesful!'
}

但是如果我为每个

await
添加一个
fetch

await fetch(endpoint, {
  method: "POST",
  headers: {
    Authorization: "Bearer " + token,
    "Content-Type": "application/json-patch+json",
    "accept": "application/json"  
  },
  body: b1
})
 .then((response) => {
  console.log(response.status)
  return response.json()
})
.then(data => {
  console.log(data);
})
.catch(error => {
  console.error('CREATE Error:', error);
});


await fetch(endpoint, {
  method: "POST",
  headers: {
    Authorization: "Bearer " + token,
    "Content-Type": "application/json-patch+json",
    "accept": "application/json"  
  },
  body: b2
})
 .then((response) => {
  console.log(response.status)
  return response.json()
})
.then(data => {
  console.log(data);
})
.catch(error => {
  console.error('CREATE Error:', error);
});


await fetch(endpoint, {
  method: "POST",
  headers: {
    Authorization: "Bearer " + token,
    "Content-Type": "application/json-patch+json",
    "accept": "application/json"  
  },
  body: b3
})
 .then((response) => {
  console.log(response.status)
  return response.json()
})
.then(data => {
  console.log(data);
})
.catch(error => {
  console.error('CREATE Error:', error);
});

它总是有效 - 所有 3 个都已成功发布:

❯ node test.js
200
{
  status: 'succesful!'
}
200
{
  status: 'succesful!'
}
200
{
  status: 'succesful!'
}

据我了解,您可以结合

await
then
,但通常您可以选择
await
方法或
then
方法。

那么在上面的例子中我做错了什么?

如何让这 3 个 post 请求每次都成功完成 仅使用

then

然后我将仅使用

await
Promise.all
来处理: https://vanillajstoolkit.com/reference/ajax/multiple-endpoints/

作为后续练习,除非我当然需要将它们与

then
结合使用。

更新:卷曲的示例始终有效(可能是因为卷曲是同步的/内部确实正确等待):

bodies.forEach(body => {
  const cmd = `curl -si -X POST -H 'accept: application/json' \
  -H 'Content-Type: application/json-patch+json' \
  -H "Authorization: Bearer ${token}" \
  -d '${body}' '${endpoint}'`
  
  const execSync = child.execSync;
  const result = execSync(cmd, { encoding: "utf-8" });
  console.log(result)
}) 

执行时:

❯ node test_curl.js
HTTP/2 200
...

HTTP/2 200
...

HTTP/2 200
...

但是基于此示例使用curl“强制”异步调用: https://serverfault.com/a/1084693/138328

提供与使用 fetch/then 时相同的不可预测/随机失败行为

node.js async-await fetch
1个回答
0
投票

在问题的评论部分,我们得出的结论是服务器不会处理过于频繁的请求或持续的请求。

这是通过发送异步 cURL 请求进行实验验证的,即使如此,问题仍然重现,这证明问题不是由于

fetch
调用本身,而是由于并行发送请求的异步性质。

© www.soinside.com 2019 - 2024. All rights reserved.