Giphy API调用返回结果顺序错乱问题求助
为什么调用Giphy API返回的GIF顺序混乱?
我现在有个功能,是遍历一个字符串数组,给每个单词调用Giphy API返回对应的GIF,功能能正常运行,但返回的结果顺序却乱了。原数组开头内容是 "STATELY, PLUMP BUCK MULLIGAN CAME FROM THE STAIRHEAD",实际展示出来的顺序却是Plump、Mulligan、Came、Buck……以下是我的相关代码:
var chapter = "STATELY, PLUMP BUCK MULLIGAN CAME FROM THE STAIRHEAD," let words = chapter.split(" "); for (i=0; i<words.length; i++){ let word = words[i]; var queryURL = "http://api.giphy.com/v1/gifs/search?q=" + word + "&api_key=<MY API KEY>"; $.ajax({ url: queryURL, method: 'GET' }) .done(function(response) { var results = response.data; var gifDiv = $('<div/>'); var gif = $('<img/>'); gif.addClass('myImg'); gif.attr('src', results[0].images.fixed_height.url); gif.attr('data-animate', results[0].images.fixed_height.url) gif.attr('data-state', 'still'); gifDiv.append(gif); gifDiv.append('<h1>' + word + '</h1>'); gifDiv.appendTo($('#gifs-here')); }) };
问题原因
这事儿本质是AJAX请求的异步特性在搞鬼!你写的循环会依次发起每个单词的API请求,但这些请求并不会乖乖按你发起的顺序等待响应——哪个请求从Giphy服务器拿到结果更快,哪个就会先触发.done()里的渲染逻辑,把对应的GIF加到页面上。
比如你先发起了"STATELY"的请求,紧接着是"PLUMP",但如果"PLUMP"的响应比"STATELY"先回来,那它就会先被插入到页面里,自然就打乱了你想要的顺序。
解决办法
想要保证顺序,有几种常用的方案:
1. 用async/await让请求串行执行
把循环改成异步函数,用await等待每个AJAX请求完成后再发起下一个,这样就能严格按原数组顺序渲染:
async function loadGifsInOrder() { var chapter = "STATELY, PLUMP BUCK MULLIGAN CAME FROM THE STAIRHEAD,"; let words = chapter.split(" "); for (let i = 0; i < words.length; i++) { let word = words[i]; var queryURL = "http://api.giphy.com/v1/gifs/search?q=" + word + "&api_key=<MY API KEY>"; // 等待当前请求完成再继续下一次循环 const response = await $.ajax({ url: queryURL, method: 'GET' }); var results = response.data; var gifDiv = $('<div/>'); var gif = $('<img/>'); gif.addClass('myImg'); gif.attr('src', results[0].images.fixed_height.url); gif.attr('data-animate', results[0].images.fixed_height.url); gif.attr('data-state', 'still'); gifDiv.append(gif); gifDiv.append('<h1>' + word + '</h1>'); gifDiv.appendTo($('#gifs-here')); } } // 调用异步函数 loadGifsInOrder();
2. 用Promise.all并行请求后按顺序渲染
如果不想等一个请求完成再发下一个(想提高效率),可以先发起所有请求,把每个请求的Promise存起来,等所有请求都完成后,再按原数组的顺序渲染结果:
var chapter = "STATELY, PLUMP BUCK MULLIGAN CAME FROM THE STAIRHEAD,"; let words = chapter.split(" "); // 把每个请求包装成Promise,同时保存对应的单词 const gifRequests = words.map(word => { var queryURL = "http://api.giphy.com/v1/gifs/search?q=" + word + "&api_key=<MY API KEY>"; return $.ajax({ url: queryURL, method: 'GET' }).then(response => ({ word, response })); }); // 等待所有请求完成后,按原顺序处理结果 Promise.all(gifRequests).then(results => { results.forEach(({ word, response }) => { var data = response.data; var gifDiv = $('<div/>'); var gif = $('<img/>'); gif.addClass('myImg'); gif.attr('src', data[0].images.fixed_height.url); gif.attr('data-animate', data[0].images.fixed_height.url); gif.attr('data-state', 'still'); gifDiv.append(gif); gifDiv.append('<h1>' + word + '</h1>'); gifDiv.appendTo($('#gifs-here')); }); });
内容的提问来源于stack exchange,提问作者Nick Tamburro
相关产品推荐
相关产品推荐

