使用一个Iron-ajax元素处理多个请求 [英] Using one iron-ajax element for multiple requests
问题描述
从理论上讲,应该可以通过设置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
的情况下,只要更改url
,params
或body
属性的元素,该元素就会执行请求.如果多个属性依次更改,则会自动删除自动生成的请求.
With
auto
set totrue
, the element performs a request whenever itsurl
,params
orbody
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.lastResponse
或this.$.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>
这篇关于使用一个Iron-ajax元素处理多个请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!