如何调用嵌套提取?

How to call a nested fetch?

我有如下有效的代码:

const url = "https://something";
let data2 = JSON.stringify({ source: "https://someimage.jpg" });
const test1 = fetch(url, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "mykey",
  },
  body: data2,
}).then((res) =>
  console.log("postHeaderResult" + res.headers.get("Operation-Location"))
);

现在,我想要做的是使用 Operation-Location header 这是一个 url 地址并发送一个 GET 请求,然后从这个新请求的body。

我已经尝试了以下代码,但它不起作用:

const url = "https://something";
let data2 = JSON.stringify({ source: "https://someimage.jpg" });
const test1 = fetch(url_to_formRecognizer, {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    "Ocp-Apim-Subscription-Key": "mykey",
  },
  body: data2,
})
  .then((res) =>
    console.log("postHeaderResult" + res.headers.get("Operation-Location"))
  )
  .then((res1) =>
    fetch(test1.headers.get("Operation-Location"), {
      method: "GET",
      headers: {
        "Ocp-Apim-Subscription-Key": "34dd609bcb5742de91e8474f0e27e88e",
      },
    }).then((res1) => console.log("finalResult" + res1 + "simple"))
  );

与此同时,如果我尝试我的代码 here,我会在 test1 上收到错误,但在我的 visual studio 中我不会收到任何编译错误不执行请求。 我什至尝试了以下行:

.catch((err) => console.log("odsPolicyRequestError" + err));

捕获错误但它也是空的。我不明白问题是什么,我做错了什么。

我们将不胜感激。

更新 1:

这是我基于答案的新代码。但是,由于我第二次打电话,我终于得到了“尚未开始”的消息。似乎在第一个调用真正结束之前,第二个调用就开始了。

 const url = "https://something";
let data2 = JSON.stringify({ source: documentUrl });
const res1 = await fetch(url, {
    method: "POST",
    headers: { 'Content-Type': 'application/json' , 'Ocp-Apim-Subscription-Key': apiKey},
    body: data2
});
if (!res1.ok) {
  console.log("postHeaderResult not okay first fetch" +  res1.status + " on first fetch");

}
console.log("header is:" + res1.headers.get("Operation-Location"), null);

const res2 = await  fetch(res1.headers.get("Operation-Location"), {
     method: "GET",
     headers: {'Ocp-Apim-Subscription-Key' : apiKey }
}).then( res2 => { return res2.text(); }).then(text => { api.output("text" + text, null); } );

你离得不远,但是:

  1. 您的调试履行处理程序正在干扰,将 fetch 中的履行值替换为 undefinedconsole.log 的 return 值)。你会想要删除它。

  2. 不要使用 test1 变量。履行值提供给履行处理程序(您的回调传递给 .then)。这就是你想要使用的。

像这样:

const url = "https://something";
let data2 = JSON.stringify({ source: 'https://someimage.jpg'});
fetch(url_to_formRecognizer, {
    method: "POST",
    headers: { 'Content-Type': 'application/json' , 'Ocp-Apim-Subscription-Key': 'mykey'},
    body: data2
}).then(res1 => fetch(res1.headers.get("Operation-Location"), {
     method: "GET",
     headers: {'Ocp-Apim-Subscription-Key' : '34dd609bcb5742de91e8474f0e27e88e' }})
).then(res2 => {
    console.log("finalResult" + res2 + "simple");
});

但请注意,这不会消耗第一个响应或第二个响应的正文。看起来你可能不需要第一个的主体,但我猜你至少需要第二个的主体。

或者,如果您可以使用 async 函数,此代码(在 async 函数中)可以使用 await 而不是 .then

const url = "https://something";
let data2 = JSON.stringify({ source: 'https://someimage.jpg'});
const res1 = await fetch(url_to_formRecognizer, {
    method: "POST",
    headers: { 'Content-Type': 'application/json' , 'Ocp-Apim-Subscription-Key': 'mykey'},
    body: data2
});
if (!res1.ok) {
    throw new Error("HTTP error " + res1.status + " on first fetch");
}
const res2 = await fetch(res1.headers.get("Operation-Location"), {
     method: "GET",
     headers: {'Ocp-Apim-Subscription-Key' : '34dd609bcb5742de91e8474f0e27e88e' }
});
if (!res2.ok) {
    throw new Error("HTTP error " + res2.status + " on second fetch");
}
console.log("finalResult" + res2 + "simple");

旁注:您的代码在 fetch API(我写的是 here)中有点步履蹒跚。 fetch 仅在 网络 错误而非 HTTP 错误时拒绝其承诺。您需要明确地检查事情是否在 HTTP 级别有效。以下是您可以这样做的方法:

const url = "https://something";
let data2 = JSON.stringify({ source: 'https://someimage.jpg'});
fetch(url_to_formRecognizer, {
    method: "POST",
    headers: { 'Content-Type': 'application/json' , 'Ocp-Apim-Subscription-Key': 'mykey'},
    body: data2
}).then(res1 => {
    if (!res1.ok) {
        throw new Error("HTTP error " + res1.status + " on first fetch");
    }
    return fetch(res1.headers.get("Operation-Location"), {
         method: "GET",
         headers: {'Ocp-Apim-Subscription-Key' : '34dd609bcb5742de91e8474f0e27e88e' }
    });
}).then(res2 => {
    if (!res2.ok) {
        throw new Error("HTTP error " + res2.status + " on second fetch");
    }
    console.log("finalResult" + res2 + "simple");
});

(或者使用 fetch 包装器为您执行 ok 检查,正如我在那个链接的博客 post 中描述的那样。)


旁注 2:始终处理 promise 拒绝(在这种情况下,末尾可能带有 .catch)或将 promise 链传递回调用者以便调用者可以检查它,这一点很重要.您的代码似乎也没有。