2013-09-22 136 views
0

我有一个功能,进行API调用,并通过第一函数的数据循环,并进行API调用每个迭代的第二功能。我试图使用异步库要做到这一点,但第2个功能仍在运行异步,而不是等待完成。所以我最终运行功能1点运行,功能2点开始,但最终的回调函数前2个完成运行。异步foreach循环进行API调用

async.series([ 
     function (callback) { 
      //api call 
      getShelves.execute(function (err, shelves) { 
      if (err) { return callback(err); } 
      async.forEach(shelves.items, function (shelf, callback) { 
       var shelfObj = {id: shelf.id, title: shelf.title, books: []}; 
       bookShelves.push(shelfObj); 
       callback(); 
      }); 

      //sort numerically to make placing books easier 
      bookShelves.sort(function (a, b) {return a.id - b.id; }); 
      callback(); 
      }); 
     }, 
     function (callback) { 
      async.forEach(bookShelves, function (shelf, callback) { 
      //api call 
      getBooks.execute(function (err, books) { 
       if (err) { return callback(err); } 
       if (books.items) { 
       async.forEach(books.items, function (book, callback) { 
        var bookObj = {title: book.volumeInfo.title}; 
        bookShelves[shelf.id].books.push(bookObj); 
        callback(); 
       }); 
       } 
       callback(); 
      }); 
      }); 
      callback(); 
     } 
     ], function (err) { 
     if (err) { console.log('error'); } 
     res.render('collection', { shelves: bookShelves }); 
     }); 
    }); 

编辑:现在工作谢谢你们

function (callback) { 
      async.forEach(bookShelves, function (shelf, callback) { 
      getBooks.execute(function (err, books) { 
       if (err) { return callback(err); } 
       if (books.items) { 
       async.forEach(books.items, function (book, callback) { 
        var bookObj = {title: book.volumeInfo.title}; 
        bookShelves[shelf.id].books.push(bookObj); 
        console.log(book.volumeInfo.title); 

        //callback to continue book loop 
        callback(); 
       }, function() { 
        //callback to continue shelf loop 
        callback(); 
       }); 
       }else{ 
       callback(); 
       } 
      }); 
      }, function() { 
      //callback to end function and move to next. However this is never reached 
      callback(); 
      }); 
     } 

回答

0

第二个功能在一系列调用其回调immidiately,而不是等到async.forEach迭代结束。相反,试试这个事后称之为:

function (callback) { 
     async.forEach(bookShelves, function (shelf, callback) { 
     //api call 
     //... skipped ... 
     }, function() { 
      callback(); 
     }); 
    } 
+0

我想你的建议,但我遇到了现在的问题是,我从不打回调在foreach调用后。任何建议? – bluegreymouse

+0

没关系我只是不需要调用回调如果books.items正好是空的。谢谢您的帮助。 – bluegreymouse

0
function loadShelf(shelf, callback) { 
    //_.pick is handy for this FYI 
    var shelfObj = {id: shelf.id, title: shelf.title}; 
    //presumably your getBooks call takes a shelf id to relate the 
    //getBooks is an asynchronous DB or API call presumably 
    getBooks(shelf.id, function (error, books) { 
    if (error) { 
     callback(error); 
     return; 
    } 
    //This is an in-memory array. No async needed. 
    shelfObj.books = books.map(function (book) { 
     return {title: book.volumeInfo.title}; 
    }); 
    callback(null, shelfObj); 
    }); 
} 

getShelves.execute(function (error, dbShelves) { 
    if (error) { 
    res.render('error', error); //pseudo-code error handling 
    return; 
    } 
    async.each(dbShelves, loadShelf, function (error, fullShelves) { 
    if (error) { 
     res.render('error', error); //pseudo-code error handling 
     return; 
    } 
    //sort numerically to make placing books easier 
    var sortedShelves = fullShelves.sort(function (a, b) {return a.id - b.id; }); 
    res.render('collection', { shelves: sortedShelves }); 
});