Javascript回调的处理速度比其他回调更快



我正在使用facebook的javascript sdk插件在我的网页上创建提要。

问题是,有时在加载过程中,即使我设置了回调链,提要也会变得无序。

我认为它是无序的,因为有时"第二个"异步调用的处理速度比"第一个"异步呼叫快。

这是我第一次使用回调,我做得对吗?

如果某些调用完成得比其他调用快,我如何解决提要无序的问题?

以下代码仅为相关代码,处于工作状态。

function initFeed(){
    FB.api('/{id}/feed', function(response){
    var feedArray = response.data;  
        $.each(feedArray, function(){
            var $this = $(this)[0]; //Status Object for single Status in Feed
            setStatus($this, processStatus); //processStatus is function defined below
        }); 
    });
}
function setStatus(statusObject, callbackProcessStatus){    
    FB.api("/{personId}?fields=id,link,name,picture",
        function (response) {   
        var html = /* Generates html based from statusObject and response */
        callbackProcessStatus(html);        
    });
}
function processStatus(html){
    $('#fb-status-wrapper').append(html);
}

(不确定这篇文章的标题,如果你认为它不够描述性,请编辑)向致以最良好的问候

这是并行异步调用的一个常见问题。最简单的解决方案需要承诺。我推荐蓝鸟承诺图书馆,但大多数都会做得很好。

var fbApi = function(url){
  return new Promise(function(resolve, reject){
    FB.api(url, function(resp){ resolve(resp); });
  });
}
function setStatus(statusObject){
  return fbApi("/{personId}?fields=id,link,name,picture")
  .then(function(response){
    var html = ...;
    return html;
  });
}
function getFeedItemPromises(){
  return fbApi("/{id}/feed").then(function(response){
    return response.data.map(function(item){
    });
  });
}

根据您的需要,initFeed可以是其中之一。第一个在所有项目都可用时渲染提要,第二个在每个项目都可用但强制执行顺序时渲染提要。

function initFeed(){
  return Promise.all(getFeedItemPromises())
  .then(function(itemsHtml){
    // append all of the items at once
    $('#fb-status-wrapper').append(itemsHtml.join("n"));
  });
}

或者这确保了顺序,但在添加了之前的所有项目后,会急切地将项目附加到提要中。

function initFeed(){
  function renderItem(html){
    $('#fb-status-wrapper').append(html);
  }
  // reduce can be used to chain promises in sequence
  return getFeedItemPromises().reduce(function(p, nextPromise){
    return p.then(function(){ return nextPromise })
     .then(renderItem);
  }, Promise.resolve())
}

另一种选择是为每个项创建一个div,作为占位符,将它们保存在数组中,并在每个项解析时填充它们。如果您事先知道项目的高度,并在加载时将其淡入,则效果尤其好。从用户体验的角度来看,这是我认为最好的。

如果你不知道物品的高度,我不推荐使用上述方法,因为插入新物品时会导致令人头痛的物品移位。

实际上,您不能依赖于请求的完成顺序。唯一可以确定的方法是,如果第一个完成,只调用第二个。但这会大大降低装载速度。

另一种可能性是记住每个请求是哪一个,并按正确的顺序插入项目(在"较晚"的请求之前插入,即使该请求是较早收到的)。

我认为最简单的方法是为每个循环中的项制作占位符,以便按正确的顺序插入占位符。当请求返回时,您只需将响应放在正确的占位符中。

它可能看起来有点像这样。两条额外的线和一些微小的变化。如果没有API,我无法测试这一点,但我希望你能明白。

function initFeed(){
    FB.api('/{id}/feed', function(response){
    var feedArray = response.data;  
        $.each(feedArray, function(index){
            var $this = $(this)[0]; //Status Object for single Status in Feed
            // Make a container per item inside the wrapper.
            var $itemContainer = $('<div></div>');
            $('#fb-status-wrapper').append($itemContainer);
            // Pass the container to the api function.
            setStatus($this, processStatus, $itemContainer); //processStatus is function defined below
        }); 
    });
}
function setStatus(statusObject, callbackProcessStatus, $container){    
    FB.api("/{personId}?fields=id,link,name,picture",
        function (response) {   
        var html = /* Generates html based from statusObject and response */
        // Pass the item place holder/container to the processing procedure.
        callbackProcessStatus(html, $container);        
    });
}
function processStatus(html, $container){
    $container.append(html);
}

相关内容

  • 没有找到相关文章

最新更新