如何为jquery AJAX 函数编写同步 Package 器[duplicate]

wz3gfoph  于 2023-01-04  发布在  jQuery
关注(0)|答案(1)|浏览(161)
    • 此问题在此处已有答案**:

(41个答案)
9小时前关门了。
我把同步的ajax调用转换成异步的,因为大多数浏览器不再支持同步调用。(和动态的)ajax调用(对于客户端函数)其中代码绝对不能继续直到调用完成,我希望我可以做一些事情,比如用waitForCompletion(asynchronousAjaxFunction());替换synchronousAjaxFunction();,但是还没有找到任何解决方案,可以让它在不把代码翻过来的情况下工作。任何帮助都将不胜感激。

ffdz8vbo

ffdz8vbo1#

首先,确保从jQuery脚本中删除所有async: false,,因为同步XHR可能会挂起主线程,导致应用程序无响应。
然后,如果您使用的jQuery版本低于3.0,请为$.ajax创建一个Promise Package 器,如下所示:

// For jQuery v. < 3.0. jQuery v. 3.0+ implement already A* Promises.
// Use $ajaxP instead of $.ajax
const $ajaxP = (opts) => new Promise((res, rej) => $.ajax(opts).done(res).fail(rej));

使用模块和 * 顶级等待 *

一种方法是将await用作top-level await(无需定义async Package 函数)-但这被认为是不良做法,因为很难推断您的程序流。如果not used correctly可能导致不希望的结果。在没有正确理解所有含义的情况下,您不应按- se重写AJAX调用,使它们 *"同步"但良好 *。

<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>

<script type="module">
console.log("Some code before...");

const data = await $.ajax({url: "https://jsonplaceholder.typicode.com/todos/1"});

console.log(data);
console.log("Some code that uses data...");

</script>

使用基于承诺的功能

你可以做的是稍微重写你的代码,让它看起来和行为都像是"同步的",方法是使用Promises并将关键的同步代码 Package 到async functions中。
下面是我们需要重写为更好的、基于Promise的方法的初始同步示例代码:
一个二个一个一个
现在你可以以类似的方式使用$ajaxP,只要确保在你的函数中使用asyncawait

const someFunction = async () => { // Make your function async
  
  console.log("Some code before...");

  const data = await $.ajax({
    url: "https://jsonplaceholder.typicode.com/todos/1"
  });
  
  console.log(data);
  console.log("Some code that uses data...");
};

someFunction();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>

为了更好地处理错误,请使用try/catch块:

const someFunction = async () => { // Make your function async
  
  let data;
  
  console.log("Some code before...");

  try {
    data = await $.ajax({
      url: "https://jsonplaceholder.typicode.com/todos/1"
    });
  } catch (err) {
    console.error(err);
    // Do something about the error and data  
  }
  
  console.log(data);
  console.log("Some code that uses data...");
};

someFunction();
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>

如果需要,还可以将$ajaxPPromise.prototype.then配合使用

$.ajax({url: "https://jsonplaceholder.typicode.com/todos/1"})
  .then((data) => {
    console.log("Some code before...");
    console.log(data)
    console.log("Some code that uses data...");
  })
  .catch(console.error);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>

或者只使用默认的jQuery方式:

$.ajax({url: "https://jsonplaceholder.typicode.com/todos/1"})
  .done((data) => {
    console.log("Some code before...");
    console.log(data)
    console.log("Some code that uses data...");
  })
  .fail(console.error);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js"></script>

您不需要jQuery

如果您有时间并且打算放弃jQuery,那么作为一个提示,您可以使用JavaScript的Fetch来代替:

fetch("https://jsonplaceholder.typicode.com/todos/1", {/* options here */})
  .then(res => res.json())
  .then((data) => {
  
    console.log("Some code before...");
    
    console.log(data)
    console.log("Some code that uses data...");
  })
  .catch(console.error);

或使用async/await:

console.log("Some code before");

(async () => {
  
  const res = await fetch("https://jsonplaceholder.typicode.com/todos/1", {/* options here */});
  const data = await res.json();
  
  console.log(data);
  console.log("Some code after that uses data");

})();

console.log("Some code after that does NOT uses data");

或者如前所述,在Module中,使用顶级wait

<script type="module">
console.log("Some code before");

const res = await fetch("https://jsonplaceholder.typicode.com/todos/1", {/* options here */});
const data = await res.json();
  
console.log(data);
console.log("Some code after that uses data");
</script>

相关问题