javascript - 如何将ajax调用结果传递给后续的ajax调用

标签 javascript jquery ajax

我目前正在尝试通过 ajax 链接来利用多个 ajax 调用,但不确定最佳方法,因为有几种方法可以通过新框架、jquery 和纯 javascript 来做到这一点。

鉴于近年来 js 的 native 开发已经有了很大改进,我更愿意使用纯原生 javascript 来做到这一点,但是,在多个 ajax 调用的情况下,我相信还有很多需要改进的地方,我相信其中之一方法是使用 promise ?我确实看到很多人通过 jquery 处理这种情况。

如果其他编码人员可以举出他们的例子,说明他们将如何根据之前的 ajax 返回的调用值编写现代方法 ajax 链调用,我将非常感激。

好的,简而言之,我试图将第一个 ajax 调用的值传递给第二个 ajax 调用,同时确定执行第二个 ajax 调用的正确方法。

下面我添加了带有注释的代码:

// Establish functionality on window load:
window.onload = function() {

    'use strict';

    // get product id on load
    var pid = document.getElementById('pid');
    var colorlist = document.getElementById('colorlist');
    var sizelist = document.getElementById('sizelist');

     colorlist.onclick = function(e) { 
    if (typeof e == 'undefined') e = window.event;

    var colorid = e.target.value

    while (sizelist.firstChild) {
    sizelist.removeChild(sizelist.firstChild);
    }

        // 2ND AJAX CALL
        var xhr = getXMLHttpRequestObject();

        xhr.open('GET', '/ajax/get_sizes.php?id=' + encodeURIComponent(pid.value) + '&colorid=' + encodeURIComponent(colorid), true);
        // set header if sending to php
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
        xhr.send(null);

        // Function to be called when the readyState changes:
        xhr.onreadystatechange = function() {

            // Check the readyState property:
            if (xhr.readyState == 4) {

                    // Check the status code:
                    if ( (xhr.status >= 200 && xhr.status < 300) 
                    || (xhr.status == 304) ) {

                    var sizes = xhr.responseText;
                    var sizes = JSON.parse(sizes);

                    for (var i = 0, num = sizes.length; i < num; i++) {

                    var label = document.createElement('label');

                    label.setAttribute ("for", sizes[i].id);
                    label.classList.add("swatch");
                    label.innerHTML = sizes[i].size;

                    var radio = document.createElement('input');

                    radio.type = "radio";
                    radio.id = sizes[i].id;
                    radio.value = sizes[i].id;
                    radio.name = "sizes";

                    sizelist.appendChild(label);
                    sizelist.appendChild(radio);

                    } //END OF FOR LOOP

                } else { // Status error!
                document.getElementById('output').innerHTML = xhr.statusText;
                }

            } // End of readyState IF.

        }; // End of onreadystatechange anonymous function.
    }; // END OF COLORLIST ONCLICK

    // 1ST AJAX CALL
    var ajax = getXMLHttpRequestObject();

        // Function to be called when the readyState changes:
        ajax.onreadystatechange = function() {

            // Check the readyState property:
            if (ajax.readyState == 4) {

                // Check the status code:
                if ( (ajax.status >= 200 && ajax.status < 300) 
                || (ajax.status == 304) ) {

                    var colors = ajax.responseText;
                    var colors = JSON.parse(colors);

                    for (var i = 0, num = colors.length; i < num; i++) {

                        var label = document.createElement('label');
                        label.setAttribute ("for", colors[i].id);
                        label.classList.add("swatch", colors[i].color);
                        label.innerHTML = colors[i].color;

                        var radio = document.createElement('input');

                        radio.type = "radio";
                        radio.id = colors[i].id;
                        radio.value = colors[i].id;
                        radio.name = "colors";

                        colorlist.appendChild(label);
                        colorlist.appendChild(radio);
                    } // END OF FOR LOOP

                } //END OF STATUS CODE CHECK
                    else { // Status error!
                    document.getElementById('output').innerHTML = ajax.statusText;
                    }

            } // End of onreadyState IF.

        }; // End of onreadystatechange anonymous function.

    ajax.open('GET', '/ajax/get_colors.php?id=' + encodeURIComponent(pid.value), true);
    // set header if sending to php
    ajax.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    ajax.send(null); 

}; // End of onload anonymous function.

问候大卫

最佳答案

欢迎来到 SO 并感谢您的提问。我将尽我所能向您展示一些示例,说明如何以一种可能更适合您作为解决方案的方式执行代码。

回调

什么是回调?

Simply put: A callback is a function that is to be executed after another function has finished executing — hence the name ‘call back’.



Source of quote

在您的代码示例中,您希望一个接一个地执行至少 2 个 HTTP 请求。这意味着一段代码必须执行两次。为此,您可以在 XMLHTTPRequest 周围编写一个函数。只写一次就可以多次执行它。

这里下面的函数有两个参数:urlcallback . url参数是一个字符串,它将被注入(inject)到 xhr.open 的第二个参数中。方法。 callback参数将是一个函数。当请求成功完成时,将调用此函数。
function get(url, callback) {
  var xhr = new XMLHTTPRequest();
  xhr.onreadystatechange = function() {
    if (xhr.readyState === 4 && xhr.status === 200) {
      if ('function' === typeof callback) {
        callback(xhr.responseText);
      }
    }
  };
  xhr.open('GET', url, true)
  xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
  xhr.send();
}

这是它如何工作的一个小例子。看到回调函数有一个参数叫做data1 .那是xhr.responseText我们从 XMLHTTPRequest 回来.在回调函数内部调用 get再次运行以发出另一个请求。
get('/ajax1.php', function(data1) {
  // Do something with data1.

  get('/ajax2.php', function(data2) {
    // Do something with data2.
  });

});

这是在另一个完成后发出请求的一种相当简单的方法。
但是如果我们有 100 个请求一个接一个怎么办?

promise 的 XMLHTTPRequest

The Promise object represents the eventual completion (or failure) of an asynchronous operation, and its resulting value.



Source of quote

输入 promise 。此处的示例与上面的示例几乎相同。只有这一次我们使用 Promise .调用get时我们立即返回 Promise .这个 promise 将等待自己到 resolvereject .在这种情况下,我们只使用 resolve对于成功的请求。每当请求完成 resolve被调用,Promise 链开始。
function get(url) {
  return new Promise(resolve => {
    var xhr = new XMLHTTPRequest();
    xhr.onreadystatechange = function() {
      if (xhr.readyState === 4 && xhr.status === 200) {
        if ('function' === typeof callback) {
          resolve(xhr.responseText);
        }
      }
    };
    xhr.open('GET', url, true)
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.send();
  });
}

因此,我们不使用回调函数,而是使用 then .内部 then我们确实使用了一个回调函数,它允许我们使用已在返回的 Promise 中解析的值. then可以链接更多 then是无限的,直到你用完要链接的东西。

在回调函数内部调用下一个请求。
get('/ajax1.php')
  .then(data1 => {
    // Do something with data1.
    get('/ajax2.php')
      .then(data2 => {
        // Do something with data2.
      });
  });

拿来

The Fetch API provides an interface for fetching resources (including across the network). It will seem familiar to anyone who has used XMLHttpRequest, but the new API provides a more powerful and flexible feature set.



Source of quote

在我们创建自己的 Promise 之前XMLHTTPRequest 的版本。但是 JavaScript 已经进化了,并且有了新的工具可以使用。 fetch有点像我们的get功能有效,但具有更多功能和选项以使其更强大。它还使用了 promise !
fetch('/ajax1.php')
  .then(response1 => response1.text())
  .then(data1 => {
    // Do something with data1.

    fetch('/ajax2.php')
      .then(response2 => response2.text())
      .then(data2 => {
        // Do something with data2.
      });

  })
  .catch(error => console.log(error));

虽然 then语法仍然使我们嵌套函数。像以前一样,当你有 100 个回调函数要调用时呢?那将是一个嵌套困惑!

获取 + 异步/等待

现在这是解决嵌套问题并使语法更像是在 JS 中分配一个简单变量的方法。 异步/等待 是现代 JavaScript 的一部分,所以要警惕不支持它的旧浏览器。查看caniuse对于当前的支持。

异步/等待 语法如下所示。使用 async 创建函数前面的关键字。就像它暗示的那样,这将表明异步代码将在此处执行。它还使函数在自动返回 Promise 之前具有异步功能。 .

在异步函数中使用 await每当您调用返回 Promise 的函数时使用关键字,如 fetch , 或我们自己的函数 get .这将返回 已解决值而不必使用 then或回调函数。
await关键字还使代码在继续执行下一行代码之前实际等待。现在你的 JS 看起来不错,并且可以用更少的嵌套编写。
(async function() {

  const response1 = await fetch('/ajax1.php');
  const data1 = await response1.text();
  // Do something with data1.

  const response2 = await fetch('/ajax2.php');
  const data2 = await response2.text();
  // Do something with data1.

}());

我真的希望这会有所帮助,并帮助您到达需要去的地方。
如果您对以上内容有任何疑问,请告诉我!

祝你有个好的一天!

关于javascript - 如何将ajax调用结果传递给后续的ajax调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58660665/

相关文章:

javascript - 使用 ngModel 选择选项

javascript - 文本选择在alert()中可见,但在html()中不可见

javascript - 将数据从 Ember 传递到 Logo 模板中的 HTML

javascript - 使用 AJAX 将数组发布到 MVC C#

javascript - jQuery/post() : the URL called is not what I expected

javascript - HTML如何在提交之前验证数组中的任何复选框

javascript - 我在做代码大战,我被困在学生的期末成绩挑战中

javascript - Vuex 状态数组键

php - 通过 AJAX 发布在 PHP 中回显 JSON 对象

javascript - webmethod返回整个html插入字符串值