简体   繁体   中英

Callback on function call in $.each

I call a function in an $.each loop, but i want to make sure, that the next iteration is not called until the previous function is done.

$(".btn_loadfavorites").on("click",function(event){
 $.getJSON('utility/get_user_compare_pages.php', {uid: user}, function(rsp) {
  $.each(rsp, function(i, favorite_pageid) {
   loadNewFacebookPage(favorite_pageid);
  });
 });  
});

Here is the function (I stripped it of the unimportant stuff):

function loadNewFacebookPage(newfbpage){

  if (isUrl(newfbpage) || newfbpage.substr(0,3) == "www"){
    newfbpage = newfbpage.substr(newfbpage.lastIndexOf('/') + 1);
  }

  $.getJSON( "https://graph.facebook.com/"+newfbpage+"?fields=picture,name,category,likes,talking_about_count,link,website" )
  .done(function( rsp ) {
      $('#loadmodal').modal('show');
      var newpageid = rsp.id;
      $("*[data-pcpageid]").each(function(i, elm) {
        if(newpageid == $(this).data("pcpageid")){
          pageexists = true;
          alert('Page has already been added');
          return;
        }
      });
      if(pageexists == false){
        pagename = rsp.name.split(" ");
        pagepicture = rsp.picture.data.url;
        $('.grid_fbpages').append("<li class='grid_li_fbpages' data-pcpageid='"+newpageid+"' style='max-width:20%;'><img src='"+pagepicture+"' class='img-circle' style='display:inline;margin-right:15px;'><h4 style='display:inline;'>"+pagename[0]+"</h4><a href='javascript:void(0)' class='btn_removefbpage' style='float:right' data-pcpageid='"+newpageid+"'>&#10005</a> <a href='javascript:void(0)' class='btn_addtofavorites' style='float:right' data-pcpageid='"+newpageid+"'>&#9733;</a><hr>Likes: "+rsp.likes+"<br>PTAT: "+rsp.talking_about_count+"<br><br></li>");
        //GET POSTS
        $.getJSON('utility/get_compare_posts.php', {access_token: access_token, pid: newpageid}, function(rsp) {
          $.each(rsp, function(postId, data) {

            //TOP POSTS
            if (data.hasOwnProperty('likes')){
              top_posts_likes.push(data.likes.like_count);
              if (data.hasOwnProperty('comments')){
                top_posts_comments.push(data.comments.comment_count);
              }else{
                top_posts_comments.push('0');
              }
              top_posts_message.push(data.message);
              top_posts_id.push(data.postId);
            }
          });

          //TOP POSTS
          $(".grid_topposts").append("<li data-pcpageid='"+newpageid+"' style='max-width:20%;text-align:left;'><img src='"+pagepicture+"' class='img-circle' style='display:inline;margin-right:15px;'><h4 style='display:inline;'>"+pagename[0]+"</h4></li>");
          most_popular_post_index = top_posts_likes.indexOf(Math.max.apply(Math, top_posts_likes));
          $.getJSON( "https://graph.facebook.com/"+top_posts_id[most_popular_post_index]+"?fields=picture&access_token="+access_token+"", function(rsp) {
            $(".grid_topposts").append("<li data-pcpageid='"+newpageid+"' style='max-width:20%;'><img src='"+rsp.picture+"'><br>"+top_posts_message[most_popular_post_index]+"<br>Likes: "+top_posts_likes[most_popular_post_index]+" Comments: "+top_posts_comments[most_popular_post_index]+"</li>");
              top_posts_likes.splice(most_popular_post_index,1);
              top_posts_message.splice(most_popular_post_index,1);
              top_posts_id.splice(most_popular_post_index,1);
              top_posts_comments.splice(most_popular_post_index,1);

              most_popular_post_index = top_posts_likes.indexOf(Math.max.apply(Math, top_posts_likes));
              $.getJSON( "https://graph.facebook.com/"+top_posts_id[most_popular_post_index]+"?fields=picture&access_token="+access_token+"", function(rsp) {
                $(".grid_topposts").append("<li data-pcpageid='"+newpageid+"' style='max-width:20%;'><img src='"+rsp.picture+"'><br>"+top_posts_message[most_popular_post_index]+"<br>Likes: "+top_posts_likes[most_popular_post_index]+" Comments: "+top_posts_comments[most_popular_post_index]+"</li>");
                  top_posts_likes.splice(most_popular_post_index,1);
                  top_posts_message.splice(most_popular_post_index,1);
                  top_posts_id.splice(most_popular_post_index,1);
                  top_posts_comments.splice(most_popular_post_index,1);

                  most_popular_post_index = top_posts_likes.indexOf(Math.max.apply(Math, top_posts_likes));
                  $.getJSON( "https://graph.facebook.com/"+top_posts_id[most_popular_post_index]+"?fields=picture&access_token="+access_token+"", function(rsp) {
                    $(".grid_topposts").append("<li data-pcpageid='"+newpageid+"' style='max-width:20%;'><img src='"+rsp.picture+"'><br>"+top_posts_message[most_popular_post_index]+"<br>Likes: "+top_posts_likes[most_popular_post_index]+" Comments: "+top_posts_comments[most_popular_post_index]+"</li>");
                      top_posts_likes.splice(most_popular_post_index,1);
                      top_posts_message.splice(most_popular_post_index,1);
                      top_posts_id.splice(most_popular_post_index,1);
                      top_posts_comments.splice(most_popular_post_index,1);
                  });
              });
          });
          //END TOP POSTS  

        });
      }
  })
  .fail(function( error ) {
    alert('Did not find any match - Please try again with another name, ID or URL');

  });
}

Thanks

$.each() is synchronous. It's just a loop that calls a function directly, nothing fancy or mysterious about it. In your code, $.each() will call loadNewFacebookPage() , that function will run to completion, and then $.each() will move on to the next element.

But is that what you're really asking about? loadNewFacebookPage() sounds like it's probably an asynchronous function. If it is, are you saying that you want to wait until the asynchronous activity has completed before moving on to the next loop iteration? The $.each() loop won't do that. Nor would an ordinary for loop. Instead, loadNewFacebookPage() would need to provide a completion callback, and that callback would advance a "loop" variable.

If you can tell more about loadNewFacebookPage() —in particular whether it has a completion callback or one could be added—then it would be more clear what to do.

For example, suppose loadNewFacebookPage() takes a second argument which is a completion callback function. Then you could write code like this:

$.getJSON( url, { uid: user }, function( rsp ) {
    var i = 0;
    next();
    function next() {
        if( i < rsp.length ) {
            var favorite_pageid = rsp[i++];
            loadNewFacebookPage( favorite_pageid, next );
        }
    }
});

Suppose that loadNewFacebookPage() were using the $.ajax() function to load the data. (It probably isn't doing that, is it? But this will serve to illustrate.) Then you might do something like:

function loadNewFacebookPage( id, done ) {
    $.ajax({
        url: makeUrlFromId( id ),
        success: function( data ) {
            doStuffWithData( data );
            done();
        }
    });
}

I'm omitting a bunch of stuff here like error handling just to illustrate an example.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM