使用一个Iron-ajax元素处理多个请求 [英] Using one iron-ajax element for multiple requests

查看:75
本文介绍了使用一个Iron-ajax元素处理多个请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从理论上讲,应该可以通过设置auto属性,然后在该元素上重复设置url属性,对多个请求使用一个iron-ajax元素. iron-ajax具有一个名为activeRequests的属性,该属性是一个只读数组,因此它似乎支持同时排队多个请求.但是实际上,它似乎不起作用.

Theoretically, it should be possible to use one iron-ajax element for multiple requests by setting the auto attribute and then repeatedly setting the url property on the element. iron-ajax has a property called activeRequests, which is a read-only array, so it seems like it has supports for queueing up multiple requests simultaneously. However in practice it does not appear to work.

例如,在下面的JS Bin中,我检索了包含单词polymer的书籍的书籍ID的列表,然后使用for循环重复设置url的值.

For example, in the JS Bin below, I retrieve a list of book IDs for books that contain the word polymer, and then use a for loop to repeatedly set the value of url.

<!doctype html>
<html>
<head>
  <meta name="description" content="single iron-ajax for multiple requests">
  <meta charset="utf-8">
  <base href="https://polygit.org/components/">
  <script href="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link href="polymer/polymer.html" rel="import">
  <link href="iron-ajax/iron-ajax.html" rel="import">
</head>
<body>
  <dom-module id="my-el">
    <template>
      <iron-ajax id="ajax"
                 url="https://www.googleapis.com/books/v1/volumes?q=polymer"
                 handle-as="json"
                 on-response="onResponse"
                 last-response="{{response}}" auto></iron-ajax>
    </template>
    <script>
      Polymer({
        is: 'my-el',
        properties: {
          response: {
            type: Object,
            notify: true
          }
        },
        onResponse: function(e) {
          var ajax = this.$.ajax;
          var originalUrl = 'https://www.googleapis.com/books/v1/volumes?q=polymer';
          var url = ajax.lastRequest.xhr.responseURL;
          if (url.includes(originalUrl)) {
            console.log('this is the first request');
            for (var i = 0; i < ajax.lastResponse.items.length; i++) {
              ajax.url = this.url(ajax.lastResponse.items[i].id);
            }            
          } else {
            console.log(ajax.lastResponse.selfLink);
          }
        },
        url: function(id) {
          return "https://www.googleapis.com/books/v1/volumes/" + id;
        }
      });
    </script>
  </dom-module>
  <my-el></my-el>
</body>
</html>

推荐答案

确实可以对多个请求使用iron-ajax,但不能在启用auto的情况下使用,否则您将点击iron-ajax去抖动器.从Polymer iron-ajax 文档:

It's indeed possible to use iron-ajax for multiple requests but not with auto enabled, or else you'll hit iron-ajax's debouncer. From the Polymer docs for iron-ajax:

auto设置为true的情况下,只要更改urlparamsbody属性的元素,该元素就会执行请求.如果多个属性依次更改,则会自动删除自动生成的请求.

With auto set to true, the element performs a request whenever its url, params or body properties are changed. Automatically generated requests will be debounced in the case that multiple attributes are changed sequentially.

在您问题的代码中:

// template
<iron-ajax auto ...>

// script
onResponse: function(e) {
  ...
  for (var i = 0; i < ajax.lastResponse.items.length; i++) {
    ajax.url = this.url(ajax.lastResponse.items[i].id);
  }
}

...您大概希望iron-ajax使用每个URL生成一个新请求,但是

...you're presumably expecting iron-ajax to generate a new request with each URL, but the debouncer collapses the requests into one (taking only the last invocation).

还应注意:response处理程序的事件详细信息(即e.detail)是对应的iron-request,其中包含AJAX响应(即e.detail.response).优选使用事件详细信息,因为它避免了来自iron-ajax的同时请求(其中this.$.ajax.lastResponsethis.$.ajax.lastRequest被异步覆盖)的竞争条件.

Also worth noting: The response handler's event detail (i.e., e.detail) is the corresponding iron-request, which contains the AJAX response (i.e., e.detail.response). Using the event detail is preferrable because it avoids a race condition in simultaneous requests from iron-ajax, where this.$.ajax.lastResponse or this.$.ajax.lastRequest are overwritten asynchronously.

onResponse: function(e) {
  var request = e.detail;
  var response = request.response;
}

要在新的URL中重用iron-ajax,请禁用auto(这将禁用去抖动器),并在更新URL后手动调用generateRequest().这将允许多个同时发生的异步请求(activeRequests将填充多个请求).

To reuse iron-ajax with a new URL, disable auto (which disables the debouncer) and manually call generateRequest() after updating the URL. This would allow multiple simultaneous async requests (and activeRequests would populate with more than one request).

// template
<iron-ajax ...>   <!-- no 'auto' -->

// script
onResponse: function(e) {
  var request = e.detail;
  var response = request.response;
  ...
  for (var i = 0; i < response.items.length; i++) {
    ajax.url = this.url(response.items[i].id);
    ajax.generateRequest();
  }
},
ready: function() {
  this.$.ajax.generateRequest(); // first request
}

这是您代码的修改版本:

Here's a modified version of your code:

<head>
  <base href="https://polygit.org/polymer+1.5.0/components/">
  <script src="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link rel="import" href="polymer/polymer.html">
  <link rel="import" href="iron-ajax/iron-ajax.html">
</head>
<body>
  <x-foo></x-foo>

  <dom-module id="x-foo">
    <template>
      <!-- We're reusing this iron-ajax to fetch more data
         based on the first response, and we don't want
         iron-ajax's debouncer to limit our requests,
         so disable 'auto' (i.e., remove the attribute
         from <iron-ajax>). We'll call generateRequest()
         manually instead.
      -->
    <iron-ajax id="ajax"
               url="https://www.googleapis.com/books/v1/volumes?q=polymer"
               handle-as="json"
               on-response="onResponse"
               on-error="onError">
      </iron-ajax>
    </template>
    <script>
      HTMLImports.whenReady(function() {
        Polymer({
          is: 'x-foo',
          onError: function(e) {
            console.warn('iron-ajax error:', e.detail.error.message, 'url:', e.detail.request.url);
          },
          onResponse: function(e) {
            var ajax = this.$.ajax;
            var originalUrl = 'https://www.googleapis.com/books/v1/volumes?q=polymer';
            var url = e.detail.url;
            if (url.includes(originalUrl)) {
              var books = e.detail.response.items || [];
              console.log('this is the first request');
              for (var i = 0; i < books.length && i < 3; i++) {
                ajax.url = this.url(books[i].id);
                console.log('fetching:', ajax.url);
                ajax.generateRequest();
              }
            } else {
              var book = e.detail.response;
              console.log('received:', e.detail.url, '"' + book.volumeInfo.title + '"');
            }
          },
          url: function(id) {
            return "https://www.googleapis.com/books/v1/volumes/" + id;
          },
          ready: function() {
            // generate first request
            this.$.ajax.generateRequest();
          }
        });
      });
    </script>
  </dom-module>
</body>

https://jsbin.com/qaleda/edit?html,控制台

这篇关于使用一个Iron-ajax元素处理多个请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆