简体   繁体   English

如何使2个异步API调用一个接一个地执行

[英]How to make 2 asynchronous API calls execute one after another

I am using facebooks javascript API to import the albums and photos from a Facebook page. 我正在使用facebooks javascript API从Facebook页面导入albumsphotos

First, I import the albums with an API call. 首先,我通过API调用导入albums

Then I import the photos of every album into arrays with another API call. 然后我将每张albumphotos导入到另一个API调用的数组中。

The final step - with another API call, I import the coverPhotos of every album so I can make a jquery mobile listView with all the albums and their coverPhotos . 最后一步 - 通过另一个API调用,我导入每张专辑的coverPhotos ,这样我就可以制作一个jquery mobile listView其中包含所有albumscoverPhotos

My code looks like this: 我的代码看起来像这样:

<script>
    var albumPhotos = new Array();
    var albumThumbnails = new Array();
    window.fbAsyncInit = function() {
        // init the FB JS SDK 
        FB.init({
            appId      : '564984346887426',       // App ID from the app dashboard
            channelUrl : 'channel.html',          // Channel file for x-domain comms
            status     : true,                    // Check Facebook Login status
            xfbml      : true                     // Look for social plugins on the page
        });

        // Additional initialization code such as adding Event Listeners goes here
        FB.api('169070991963/albums', function(response) {
            if(!response || response.error) {
                // render error
                alert("Noo!!");
            } else {
                // render photos
                for(var i=0; i<response.data.length; i++) { 
                    (function (i) {
                        var albumName = response.data[i].name;
                        var albumCover = response.data[i].cover_photo;
                        var albumId = response.data[i].id;
                        var numberOfPhotos = response.data[i].count;

                        FB.api(albumId + "/photos", function(response) {
                            if(!response || response.error) {
                                // render error
                                alert("Noo!!");
                            } else {
                                for(var k=0; k<response.data.length; k++) { 
                                    albumThumbnails[i] =  albumThumbnails[i]||[];
                                    albumThumbnails[i][k] = response.data[k].picture;
                                    albumPhotos[i] = albumPhotos[i]||[];
                                    albumPhotos[i][k] = response.data[k].source;
                                }
                            }
                        }); 

                        console.log(albumName);
                        FB.api( albumCover, function(response) {
                            if(!response || response.error) {
                                // render error
                                alert("Noo!!");
                            } else {
                                // render photos
                                $(".albums").append(
                                    '<li>'+
                                        '<a href="#Gallery' + i + '"' + 'data-transition="slidedown">'+
                                            '<img src= "' + response.picture + '"  />'+
                                            '<h2>' + albumName + '</h2>'+
                                            '<p>' + "Number of Photos:  " + numberOfPhotos +'</p>'+
                                        '</a>'+
                                    '</li>')
                                    .listview('refresh');

                                $("#home").after('<div data-role="page" data-add-back-btn="true" id=Gallery'+ i +
                                    ' class="gallery-page"> ' +
                                    ' <div data-role="header"><h1>Gallery</h1></div> ' + ' <div data-role="content"> ' +
                                    ' <ul class="gallery"></ul> ' + ' </div> ' +
                                    ' </div> ');

                                for(var x=0; x < albumPhotos[i].length; x++)
                                    $('#Gallery' + i + ' .gallery').append('<li><a href="' + albumPhotos[i][x] + '" rel="external"><img src="' +  albumThumbnails[i][x] + '" /></a></li>');                                                             
                            }
                        });                             
                    })(i);                                      
                } //end of for loop
            }
        });     
    };

I have a problem in this piece of code: 我在这段代码中遇到了问题:

for(var x=0; x < albumPhotos[i].length; x++)
    $('#Gallery' + i + ' .gallery').append('<li><a href="' + albumPhotos[i][x] + '" rel="external"><img src="' +  albumThumbnails[i][x] + '" /></a></li>');

and more specifically here : albumPhotos[i].length 更具体地说: albumPhotos[i].length

Because the calls to the API are asynchronous, the previous API call that actually creates the array albumPhotos has not finished yet, meaning the array is not defined yet. 因为对API的调用是异步的,所以实际创建数组albumPhotos的先前API调用还没有完成,这意味着数组尚未定义

I need a way before I call the last API call FB.api(albumCover, function(response) {..} 在调用最后一个API调用FB.api(albumCover, function(response) {..}之前我需要一种方法FB.api(albumCover, function(response) {..}

to make sure that the previous API call: 确保以前的API调用:

FB.api(albumId + "/photos", function(response) {
    if(!response || response.error) {
        // render error
        alert("Noo!!");
    } else {
        for(var k=0; k<response.data.length; k++) { 
            albumThumbnails[i] =  albumThumbnails[i]||[];
            albumThumbnails[i][k] = response.data[k].picture;
            albumPhotos[i] = albumPhotos[i]||[];
            albumPhotos[i][k] = response.data[k].source;
        }
    }
});

has finished. 已完成。

What is the easiest way to do something like this here? 在这里做这样的事最简单的方法是什么?

Short answer, you need to make all the code that depends on the albums being populated work after they get populated. 简短的回答,您需要在填充后填写依赖于填充的相册的所有代码。 That means copy and pasting some code around. 这意味着复制和粘贴一些代码。

Long answer... 答案很长......

First, let's refactor a bit. 首先,让我们重构一下。 For your sanity, you'll want this function 为了您的理智,您将需要此功能

// checkForErrorFirst wraps your function around the error checking code first
// if there is no response, then your code will not be called
// this allows you to just write the juicy working code 
//   and not worry about error checking
function checkForErrorFirst(myFunc) {
  return function(response) { 
    if (!response || response.error) {
      alert("Noo!!");
    } else {
      myFunc(response);
    }
  };
}

So that you can do things like this: 这样你就可以做到这样的事情:

function DoWork(response) {
  // usefulwork...
}

And the FB call looks like... FB的电话看起来像......

FB.api('169070991963/albums', checkForErrorFirst(DoWork));

Now that we have settled that, we need to chain each of your call together since they depend on each other. 现在我们已经解决了这个问题,我们需要将你们的每个呼叫链接在一起,因为它们彼此依赖。 I set albumPhotos and albumThumbnails in the global space just like you did. 我像你一样在全球空间设置了albumPhotos和albumThumbnails。

var albumPhotos = new Array();
var albumThumbnails = new Array();

function getAlbums(response) {
  for (var i=0; i < response.data.length; ++i) {
    processAlbum(response.data[i], i);
  } 
}

function processAlbum(album, i) {
  FB.api(album.id + "/photos", checkForErrorFirst(populateAlbum(album, i)));
}

function populateAlbum(album, i) {
  return function(response) {
    for (var k=0; k < response.data.length; ++k){ 
      albumThumbnails[i] =  albumThumbnails[i]||[];
      albumThumbnails[i][k] = response.data[k].picture;
      albumPhotos[i] = albumPhotos[i]||[];
      albumPhotos[i][k] = response.data[k].source;
    }

    // now that we've populated the album thumbnails and photos, we can render the album
    FB.api(album.cover_photo, checkForErrorFirst(renderAlbum(album, i)));
  };
}

function renderAlbum(album, i) {
  return function(response) {
    var albumName = album.name;
    var albumCover = album.cover_photo;
    var albumId = album.id;
    var numberOfPhotos = album.count;

    // render photos
    $(".albums").append('<li>'+
      '<a href="#Gallery' + i + '"' + 'data-transition="slidedown">'+
      '<img src= "' + response.picture + '"  />'+
      '<h2>' + albumName + '</h2>'+
      '<p>' + "Number of Photos:  " + numberOfPhotos +'</p>'+
      '</a>'+
      '</li>').listview('refresh');

    $("#home").after('<div data-role="page" data-add-back-btn="true" id=Gallery'+ i +
     ' class="gallery-page"> ' +
     ' <div data-role="header"><h1>Gallery</h1></div> ' + ' <div data-role="content"> ' +
     ' <ul class="gallery"></ul> ' + ' </div> ' +
     ' </div> ');


    for(var x=0; x < albumPhotos[i].length; x++)
      $('#Gallery' + i + ' .gallery').append('<li><a href="' + albumPhotos[i][x] 
        + '"  rel="external"><img src="' +  albumThumbnails[i][x] + '" /></a></li>');
  };
}

// start the entire process
FB.api('169070991963/albums', checkForErrorFirst(getAlbums));

Clearly I have not tested this - but I think this will help your sanity a bit. 很明显我没有测试过这个 - 但我认为这有助于你的理智。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 一个接一个地执行异步进程 - Execute asynchronous processes one after another Javascript - 一个接一个地执行调用 - Javascript - Execute calls one AFTER another 防止异步javascript函数调用(一个接一个的多个函数) - Prevent Asynchronous javascript function calls(multiple function one after another) 如何确保仅在另一组异步函数调用完成之后才发生一堆异步函数调用? - How to ensure that a bunch of asynchronous function calls occur only after another bunch of asynchronous function calls are complete? 在递归异步ajax调用之后执行函数 - Execute a function after the recursive asynchronous ajax calls 如何在react js中的循环和条件语句中进行异步api调用? - How to make asynchronous api calls in loop and conditional statements in react js? 如何一个接一个地调用异步function? - How to call one asynchronous function after another? javascript中如何使函数同步执行? 或者如何让函数一个接一个地执行? - How to make functions execute synchronously in javascript? or how to make functions execute one after another? 如何一个接一个地执行三个异步函数 - how to execute three asynchronous functions one after one Javascript使函数一个接一个地执行 - Javascript make functions execute one after another
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM