2012-03-02 27 views
40

Yerel olarak bir dosya listesi alan ve bunları bir sunucuya yükleyen bir Node.js uygulamasına sahibim. Bu liste binlerce dosya içerebilir.Node.js'de eşzamansız çağrıları sınırlama

for (var i = 0; i < files.length; i++) { 
    upload_file(files[i]); 
} 

Ben binlerce dosya ile bu çalıştırırsak, upload_file seferde kez tüm binlerce denilen alacak ve büyük olasılıkla kalıp (veya en azından mücadele). Senkronize dünyada, bir iş parçacığı havuzu oluşturarak belirli bir sayıda iş parçacığına sınırlardık. Kaç eşzamanlı çağrının bir seferde gerçekleştirileceğini sınırlamanın basit bir yolu var mı?

+0

(sn/dakika) benzer ancak hız limiti burada: https://stackoverflow.com/questions/20253425/throttle-and-queue-up-api-requests-due-to-per- ikinci kapak –

cevap

6

Kuyruklamayı denemelisiniz. upload_file() tamamlandığında bir geriçağırımın başlatıldığını varsayalım. Böyle bir şey (denenmemiş) hile yapmak gerekir:

function upload_files(files, maxSimultaneousUploads, callback) { 
    var runningUploads = 0, 
     startedUploads = 0, 
     finishedUploads = 0; 

    function next() { 
     runningUploads--; 
     finishedUploads++; 

     if (finishedUploads == files.length) { 
      callback(); 
     } else { 
      // Make sure that we are running at the maximum capacity. 
      queue(); 
     } 
    } 

    function queue() { 
     // Run as many uploads as possible while not exceeding the given limit. 
     while (startedUploads < files.length && runningUploads < maxSimultaneousUploads) { 
      runningUploads++; 
      upload_file(files[startedUploads++], next); 
     } 
    } 

    // Start the upload! 
    queue(); 
} 
19

yukarıdaki cevap, re: NPM üzerinde async iyi cevaptır, ancak kontrol akışı hakkında daha fazla bilgi edinmek isterseniz:


Kontrol akış düzenlerine bakmalısınız. Chapter 7 of Mixu's Node Book'da kontrol akışı düzenleri hakkında harika bir tartışma var. Yani, örneğe, 7.23: Sınırlı paralelde bakıyorum - döngü için sınırlı bir eşzamansız, paralel, eşzamanlılık.

Ben onu örnek adapte ettik:

function doUpload() { 
    // perform file read & upload here... 
} 

var files = [...]; 
var limit = 10;  // concurrent read/upload limit 
var running = 0;  // number of running async file operations 

function uploader() { 
    while(running < limit && files.length > 0) { 
     var file = files.shift(); 
     doUpload(file, function() { 
      running--; 
      if(files.length > 0) 
       uploader(); 
     }); 
     running++; 
    } 
} 

uploader(); 
+0

İyi çalışır ve yalnızca belirtilen sayıda async işlemini çalıştırır; beklenen değer, örneğin 'console.log (dosya) içermez' aynı dosyayı 10 kez yazdırır; - ancak ben doUpload' 'içeride Dosya '' değeri ('çalıştıran' önce mesela) fark ilk 10 satır ('limit' 10 değerine sahipse) – golimar

62

Her zamanki gibi Caolan McMahon async module öneriyoruz.

ikinci parametre var gibi upload_file işlevi geri arama almak Make:

var async = require("async"); 

function upload_file(file, callback) { 
    // Do funky stuff with file 
    callback(); 
} 

var queue = async.queue(upload_file, 10); // Run ten simultaneous uploads 

queue.drain = function() { 
    console.log("All files are uploaded"); 
}; 

// Queue your files for upload 
queue.push(files); 

queue.concurrency = 20; // Increase to twenty simultaneous uploads 
+1

Bu, işleri yapmanın doğru yolu. – Tyguy7

1

diğerleri cevaplar güncelliğini yitirmiş görünmektedir. Bu, async'dan paralleLimit kullanılarak kolayca çözülebilir. Nasıl kullanılacağı aşağıdadır. Ben test etmedim.

var tasks = files.map(function(f) { 
    return function(callback) { 
     upload_file(f, callback) 
    } 
}); 

parallelLimit(tasks, 10, function(){ 
}); 
+3

, sıra fonksiyonu ve parallellimit arasında bir fark var mı? – lizlalala