运行 tumblr API 使用不同的参数调用两次 return 不同的数据
Run tumblr API call twice with different params to return different data
我正在尝试 运行 一个函数,两次为函数 运行 传递不同的参数。
虽然我认为在正确的时间传递了正确的参数,但在某些时候我的变量被更新了,我不确定何时或为什么。
这是我稍微简化的js:
// randomFilter
const postContent = $('.posts');
const limit = 1;
let index = 0;
let tag;
const retrievePosts = () => {
const protocol = document.location.protocol;
const baseURL = 'api.tumblr.com/v2/blog/';
const blog = 'studio-lukeharby.tumblr.com';
if (index === 0) {
tag = 'cubes';
} else if (index === 1) {
tag = 'objects';
}
console.log('index at start:', index);
$.ajax({
type: 'GET',
url: `${protocol}//${baseURL}${blog}/posts`,
dataType: 'jsonp',
data: {
api_key: sw._site.tumblrAPIKey,
tag: tag
},
success: function(data){
let randomNumber;
randomNumber = Math.floor(Math.random() * data.response.total_posts);
console.log(`1st api call tag: ${tag}`);
$.ajax({
type: 'GET',
url: `${protocol}//${baseURL}${blog}/posts`,
dataType: 'jsonp',
data: {
api_key: sw._site.tumblrAPIKey,
offset: randomNumber,
tag: tag,
limit: limit
},
success: function(data) {
postContent.append(`<li><img src='${data.response.posts[0].photos[0].original_size.url}' alt='[${data.response.posts[0].tags}]' /></li>`);
setImgProps();
setWrapperProps();
console.log('randomNumber:', randomNumber, 'posts:', data.response.total_posts);
console.log(`2nd api call tag: ${tag}`);
}
});
},
error: function(error){
pageWrapper.empty();
pageWrapper.append('<p class="content errorInfo">Sorry there was an issue retrieving the data</p>');
postContent.remove();
elem.removeClass(loadingClass);
console.log(error.statusText);
},
complete: function() {
}
});
}
const initCounter = () => {
while (index < 2) {
index++
retrievePosts();
console.log('index:', index, 'tag:', tag);
}
};
postContent.empty();
initCounter();
我有一个工作示例jsfiddle
理论上,该函数应该查找标记为 'cubes'
的 post 并检查带有该标记的总数 post,然后检查其中的 return 1 个位于随机的。然后它应该通过下一个标签,通过偏移参数检查 posts 和 return 的总数。所以理论上,每个周期都应该 post 被 returned。
哈尔普
上面代码的问题在于 tag
是全局范围的。所以这是正在发生的事情:
- 您更改索引并调用您的
retrievePost
函数
tag
已更新,您的 ajax 呼叫被放入队列中,稍后 运行
- 您更改索引并调用您的
retrievePost
函数
tag
已更新,您的 ajax 呼叫被放入队列中,稍后 运行
- 您的两个 ajax 呼叫都从队列中取出并且 运行 具有相同的值
tag
将 let tag;
放在 retrievePost
函数中,tag
应该是正确的,尽管您将无法再在 initCounter
函数中打印它。你也可以这样做:
const postContent = $('.posts');
const limit = 1;
let index = 0;
let outerTag;
const retrievePosts = () => {
const protocol = document.location.protocol;
const baseURL = 'api.tumblr.com/v2/blog/';
const blog = 'studio-lukeharby.tumblr.com';
let tag;
if (index === 0) {
tag = 'cubes';
} else if (index === 1) {
tag = 'objects';
}
outerTag = tag;
...
}
const initCounter = () => {
while (index < 2) {
index++
retrievePosts();
console.log('index:', index, 'tag:', outerTag);
}
};
问题是范围。
tag 是您代码中的全局变量。当您使用 ajax 在循环中调用函数时,ajax 函数不要等待 ajax 完成并返回 returns。
你的第一个电话没有打完,第二个电话已经打完了。并且因为标签被定义为全局变量,所以它可以在任何地方改变。
所以首先你得到标签= 'cubes'
在你更改标签后不久 = 'objects'.
解决方案是将标签作为参数传递,这样如果您有 100 次调用,每个调用都会有自己的标签。不是普通变量。
你应该让它变得动态,比如如果你有更多的标签,比如 100 那么你会为每个标签都这样做吗..我没有解决这个问题,但你应该这样做。
const initCounter = () => {
while (index <= 1) {
index++;
if (index === 1) {
retrievePosts('cubes');
} else if (index === 2) {
retrievePosts('objects');
}
console.log('index:', index, 'tag:', tag);
}
};
并在函数中添加参数
const retrievePosts = (tags) => {
// remove the if block for index check
// and change "tag" to "tags" everywhere in this function.
}
修改后的结果如下:
这是之前的结果
我正在尝试 运行 一个函数,两次为函数 运行 传递不同的参数。
虽然我认为在正确的时间传递了正确的参数,但在某些时候我的变量被更新了,我不确定何时或为什么。
这是我稍微简化的js:
// randomFilter
const postContent = $('.posts');
const limit = 1;
let index = 0;
let tag;
const retrievePosts = () => {
const protocol = document.location.protocol;
const baseURL = 'api.tumblr.com/v2/blog/';
const blog = 'studio-lukeharby.tumblr.com';
if (index === 0) {
tag = 'cubes';
} else if (index === 1) {
tag = 'objects';
}
console.log('index at start:', index);
$.ajax({
type: 'GET',
url: `${protocol}//${baseURL}${blog}/posts`,
dataType: 'jsonp',
data: {
api_key: sw._site.tumblrAPIKey,
tag: tag
},
success: function(data){
let randomNumber;
randomNumber = Math.floor(Math.random() * data.response.total_posts);
console.log(`1st api call tag: ${tag}`);
$.ajax({
type: 'GET',
url: `${protocol}//${baseURL}${blog}/posts`,
dataType: 'jsonp',
data: {
api_key: sw._site.tumblrAPIKey,
offset: randomNumber,
tag: tag,
limit: limit
},
success: function(data) {
postContent.append(`<li><img src='${data.response.posts[0].photos[0].original_size.url}' alt='[${data.response.posts[0].tags}]' /></li>`);
setImgProps();
setWrapperProps();
console.log('randomNumber:', randomNumber, 'posts:', data.response.total_posts);
console.log(`2nd api call tag: ${tag}`);
}
});
},
error: function(error){
pageWrapper.empty();
pageWrapper.append('<p class="content errorInfo">Sorry there was an issue retrieving the data</p>');
postContent.remove();
elem.removeClass(loadingClass);
console.log(error.statusText);
},
complete: function() {
}
});
}
const initCounter = () => {
while (index < 2) {
index++
retrievePosts();
console.log('index:', index, 'tag:', tag);
}
};
postContent.empty();
initCounter();
我有一个工作示例jsfiddle
理论上,该函数应该查找标记为 'cubes'
的 post 并检查带有该标记的总数 post,然后检查其中的 return 1 个位于随机的。然后它应该通过下一个标签,通过偏移参数检查 posts 和 return 的总数。所以理论上,每个周期都应该 post 被 returned。
哈尔普
上面代码的问题在于 tag
是全局范围的。所以这是正在发生的事情:
- 您更改索引并调用您的
retrievePost
函数 tag
已更新,您的 ajax 呼叫被放入队列中,稍后 运行- 您更改索引并调用您的
retrievePost
函数 tag
已更新,您的 ajax 呼叫被放入队列中,稍后 运行- 您的两个 ajax 呼叫都从队列中取出并且 运行 具有相同的值
tag
将 let tag;
放在 retrievePost
函数中,tag
应该是正确的,尽管您将无法再在 initCounter
函数中打印它。你也可以这样做:
const postContent = $('.posts');
const limit = 1;
let index = 0;
let outerTag;
const retrievePosts = () => {
const protocol = document.location.protocol;
const baseURL = 'api.tumblr.com/v2/blog/';
const blog = 'studio-lukeharby.tumblr.com';
let tag;
if (index === 0) {
tag = 'cubes';
} else if (index === 1) {
tag = 'objects';
}
outerTag = tag;
...
}
const initCounter = () => {
while (index < 2) {
index++
retrievePosts();
console.log('index:', index, 'tag:', outerTag);
}
};
问题是范围。
tag 是您代码中的全局变量。当您使用 ajax 在循环中调用函数时,ajax 函数不要等待 ajax 完成并返回 returns。
你的第一个电话没有打完,第二个电话已经打完了。并且因为标签被定义为全局变量,所以它可以在任何地方改变。
所以首先你得到标签= 'cubes' 在你更改标签后不久 = 'objects'.
解决方案是将标签作为参数传递,这样如果您有 100 次调用,每个调用都会有自己的标签。不是普通变量。
你应该让它变得动态,比如如果你有更多的标签,比如 100 那么你会为每个标签都这样做吗..我没有解决这个问题,但你应该这样做。
const initCounter = () => {
while (index <= 1) {
index++;
if (index === 1) {
retrievePosts('cubes');
} else if (index === 2) {
retrievePosts('objects');
}
console.log('index:', index, 'tag:', tag);
}
};
并在函数中添加参数
const retrievePosts = (tags) => {
// remove the if block for index check
// and change "tag" to "tags" everywhere in this function.
}
修改后的结果如下:
这是之前的结果