如何使javascript fetch同步?

Nab*_*han 12 javascript json asynchronous fetch-api

我正在使用fetch从api获取数据json.工作正常,但我必须重复使用它进行各种调用,因此它需要是同步的,否则我需要一些方法来在每个组件的提取完成时更新接口.

function fetchOHLC(yUrl){
    fetch(yUrl)
    .then(response => response.json())
    .then(function(response) {
                alert(JSON.stringify(response.query));

            var t = response.created;
            var o = response.open;
            var h = response.high;
            var l = response.low;
            var c = response.close;

        return {t,o,h,l,c};

    })
    .catch(function(error) {
        console.log(error);
    });    
}

var fetchData = fetchOHLC(yUrl);
alert(fetchData); // empty ?
Run Code Online (Sandbox Code Playgroud)

除了使用fetch之外,还有其他方法可以实现吗?(我不想优先使用jquery).

谢谢

编辑

问题是关于fetch-api,而不是ajax,而不是jquery,所以请不要在没有正确阅读的情况下将其标记为重复这些问题.如果您仍然觉得有必要这样做,请停止将其与十年前的问题和答案联系起来,十年后会发生很多变化.

RiZ*_*KiT 26

fetch仅用于异步调用,但有一些选项:

选项1

如果XMLHttpRequest也可以,那么您可以使用async: false,这将执行同步调用。

自 2014 年以来,whatwg 规范中就出现了弃用警告,并且一些浏览器已经在开发工具中抱怨。因此可以假设它迟早将不再起作用。

选项2

使用async/await它在底层是异步的,但感觉它是同步的,请参阅/sf/answers/3846561911/

选项3

否则,当每个组件的获取完成时,我需要某种方法来更新界面

这听起来像fetch+Promise.all()很合适,请参阅/sf/answers/3640953151/

选项4

如果您想在离开页面时发送分析数据或会话数据(例如在 中onbeforeunload),并希望确保数据发送到服务器,而普通的异步 AJAX 调用无法保证这一点,您可以使用Beacon API Navigator.sendBeacon()

  • 我不敢相信没有办法做到这一点。在一种合法的情况下,只有进行同步 xhr 才有意义。在“beforeunload”事件处理程序中。这意味着在我现在正在进行的项目中,我必须 _mock_ axios 因为他们使用了它。并使用“XMLHttpRequest”代替。很有趣不是吗? (3认同)

Jon*_*lms 9

你希望你的fetch函数返回:

function fetchOHLC(yUrl){
    return fetch(yUrl)
    .then(response => response.json())
    .then(function(response) {
            alert(JSON.stringify(response.query));

        var t = response.created;
        var o = response.open;
        var h = response.high;
        var l = response.low;
        var c = response.close;

    return {t,o,h,l,c};

    })
    .catch(function(error) {
        console.log(error);
    });    
}
Run Code Online (Sandbox Code Playgroud)

现在fetchData包含一个可以很容易使用的promise:

var fetchData = fetchOHLC(yUrl);
fetchData.then(alert); //not empty ! its {t,o,h,l,c}
Run Code Online (Sandbox Code Playgroud)

如果你想要一些花哨的ES7,你可以像这样重写整个事情:

async function fetchOHLC(yUrl){
  try{
    var r=JSON.parse(await fetch(yUrl))
    alert(JSON.stringify(r.query));
    return {t:r.created,o:r.open,h:r.high,l:r.low,c:r.close};
  }catch(e){console.log(e);}
}

(async function(){
  var fetchData = await fetchOHLC(yUrl);
  alert(fetchData);
})()
Run Code Online (Sandbox Code Playgroud)

  • 这提供了合理的建议,表明该问题可能会被误导,但并没有回答问题。 (11认同)
  • 是的,这是一个糟糕的答案,令人遗憾的是堆栈溢出社区充满了这么多像你一样思考的人。问题是“如何在 javascript 中发出同步提取请求”,您的答案没有回答,而是选择居高临下地回答如何完成正常的提取。 (8认同)
  • 我知道我正在评论一个四年前的问题,但在某些罕见的情况下,发出同步网络请求是有意义的,并且在我看来是合法的。例如,我正在发出同步 Web 请求来下载存储在静态文件(例如 settings.json)中的 API 所需的 OAuth 设置(client_id 和权限)。该文件还可以使用缓存控制进行大量缓存。MDN Web 文档解释了如何执行此操作:https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests#example_http_synchronous_request (7认同)
  • 我不是专家,但是 api 绝对需要的(初始)值又如何呢?如果没有这些值,整个 javascript 的其余部分就没有任何意义了? (3认同)
  • @matthew,如果你真的想要_that_答案:使用[同步XmlHttpRequest](https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Synchronous_and_Asynchronous_Requests#synchronous_request)。但它在所有浏览器中均已弃用。不客气。 (2认同)
  • @JonasWilms `XMLHttpRequest` 可能已被弃用,但您的浏览器中仍然有一些严格同步的浏览器 API。今天。与 WebRequest 一样,是保护浏览器的唯一有效方法(拦截 SSL 无效)。如果您不想每次都使用 JavaScript 重新发明轮子(也就是让浏览器膨胀),您需要在该级别严格完全同步 Web 请求。**这里不能使用异步、等待、承诺或其他回调。在所有当前的浏览器中。**(Chrome 试图停止使用 Manifest v3 来支持 WebRequest。看起来 Mozilla 在这方面更聪明一些..) (2认同)
  • @johannes_lalala 而不是 `init(); main();` 调用 `init().then(() => main())` 并使用 `async function init() { ..; 等待获取(URL);..}`。然而这仅适用于顶层。[但不在 webRequest/onBeforeRequest 的回调中](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/webRequest/onBeforeRequest) 必须严格同步返回一些内容,所以你不能在此类回调中等待异步操作。 (2认同)
  • **我确实知道“fetch”不需要同步**,但 Chrome 扩展“chrome.webRequest.onBeforeRequest.addListener”不会让我执行异步操作。我们来这里是因为我们有自己的充分理由。 (2认同)

Mat*_*bin -1

如果您不想使用 fetch api,则必须使用回调、事件侦听器、XMLHttpRequest。

  • 正如目前所写的,您的答案尚不清楚。请[编辑]添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。您可以[在帮助中心](/help/how-to-answer)找到有关如何写出好的答案的更多信息。 (3认同)