2013-03-29 6 views
5

Tôi là một người ăn xin trong node.js và bây giờ tôi đang cố gắng để có được một số kết quả của API. Tôi đang sử dụng mô-đun không đồng bộ (https://github.com/caolan/async) để song song yêu cầu để có thể tối ưu hóa.Lỗi mô-đun không đồng bộ với các yêu cầu API song song

Vấn đề là mã được trả lại một lỗi mà mỗi thời điểm để một dòng khác nhau ("callback (err, dữ liệu)" line) trong một cuộc gọi API khác nhau

Đó là là lỗi:

if (called) throw new Error("Callback was already called."); 
         ^
Error: Callback was already called. 

tôi đang sử dụng các chức năng sau đây để yêu cầu API:

function getData(s, apiURL, getURL, callback) { 

    var ht; 
    if (s == 1) { 
     ht = https; 
    } else { 
     ht = http; 
    } 

    var options = { 
     hostname : apiURL, 
     path : getURL, 
     method : 'GET' 
    } 

    var content = ""; 

    ht.get(options, function(res) { 
     console.log("Got response: " + res.statusCode); 

     res.on("data", function(chunk) { 

      content += chunk; 
      //console.log(content); 
      callback(content); 
     }); 

    }).on('error', function(e) { 
     console.log("Error: " + e.message); 
     console.log(e.stack); 
    }); 
} 

để minh họa, đây là cách tôi đang sử dụng các mô-đun async:

var sources = sources.split(',') 

    async.parallel({ 
     flickr : function(callback) { 
      if (sources[0] == 1) { 
       getData(0, 'api.flickr.com', 
       "/services/rest/?method=flickr.photos.search&format=json&nojsoncallback=1&api_key=" + config.flickr.appid + "&per_page=5&tags=" + tags, 

       function(data) { 
        callback(null, data); //here that the error may point 
       }); 

      } else { callback(); } 
     }, 
     instagram : function(callback) { 
      if (sources[1] == 1) { 

       getData(1, 'api.instagram.com', 
       "/v1/tags/" + tags.split(',')[0] + "/media/recent?client_id=" + config.instagram, 
       function(data) {       
        callback(null, data); //here that the error may point 

       }); 
      } else { callback(); } 
     } 
    }, function(err, results) {    
      console.log(results); 
     }); 

Hy vọng bạn có thể giúp tôi, cảm ơn!

Trả lời

12

Bạn đang gọi hàm gọi lại bên trong sự kiện data (see the docs), được kích hoạt mỗi khi nhận được một đoạn dữ liệu, điều đó có nghĩa là nhiều lần.

Async.parallel đang chờ cuộc gọi lại chỉ được thực thi một lần cho mỗi tác vụ.

Để đảm bảo chỉ có một cuộc gọi lại cho mỗi công việc, hãy đặt lại cuộc gọi trên một sự kiện end.

Ngoài ra, sự kiện lỗi cũng sẽ thực hiện cuộc gọi lại.