运行 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 是全局范围的。所以这是正在发生的事情:

  1. 您更改索引并调用您的 retrievePost 函数
  2. tag 已更新,您的 ajax 呼叫被放入队列中,稍后 运行
  3. 您更改索引并调用您的 retrievePost 函数
  4. tag 已更新,您的 ajax 呼叫被放入队列中,稍后 运行
  5. 您的两个 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.
}

修改后的结果如下:

这是之前的结果