限制并发操作nodejs

时间:2017-10-07 19:21:27

标签: node.js event-loop requestjs

这是一个用节点js编写的网页抓取代码。
当队列有足够的URL时,此代码是否始终保持5个并发请求? 为什么控制台会显示其他内容?

--- yours
+++ mine
@@ -1,3 +1,4 @@
+from PyQt5 import QtWidgets
 from PyQt5 import QtCore, QtMultimedia
 from PyQt5.QtCore import QObject, pyqtSlot, pyqtSignal, QByteArray, QIODevice, QFileInfo
 from PyQt5.QtMultimedia import QAudioDecoder, QAudioFormat, QMediaObject, QAudioBuffer, QAudioOutput, QAudio
@@ -14,9 +15,9 @@

     self.decoder = QAudioDecoder()
     self.decoder.setAudioFormat(self.desiredFormat)
-    self.decoder.setSourceFilename('D:\\python\\sounds\\30.mp3')
-    fs = QFileInfo()
-    print('MP3 exists:' + str(fs.exists('D:\\python\\sounds\\30.mp3')))
+    fs = QFileInfo('test.wav')
+    self.decoder.setSourceFilename(fs.absoluteFilePath())
+    print('File exists:' + str(fs.exists()))

     #self.connect(decoder,bufferReady(),None,readBuffer())
     self.decoder.bufferReady.connect(self.readBuffer)
@@ -34,9 +35,9 @@
     self.decoder.start()
     print('Init finished, Decoder started?')
   def bufferAvailableChanged(self):
-   print(str(decoder.available))
+   print(str(self.decoder.bufferAvailable()))
   def positionChanged(self):
-    print(str(decoder.position())+'/'+str(decoder.duration))
+    print(str(self.decoder.position())+'/'+str(self.decoder.duration()))
   def stateChanged(self):
     #Confirm state is what we expect
     print('Decoder state changed?')
@@ -48,14 +49,23 @@
   def readBuffer(self):
     print('Decoder ready for reading?')
     buffer = self.decoder.read()
-    print('Bytecount in buffer:' + str(buffer.byteCount))
+    count = buffer.byteCount()
+    print('Bytecount in buffer:' + str(count))
     if self.readamount == 0:
       self.ba = QByteArray()
-      self.ba.fromRawData(buffer.data(),buffer.byteCount())
+      self.ba.fromRawData(buffer.constData().asstring(count))
+      self.readamount = count
     else:
-      self.ba.append(buffer.data(),buffer.byteCount())
+      self.ba.append(buffer.constData().asstring(count))
     print('Bytearray size:' + str(self.ba.length()))
   def play(self):
     print('Decoding finished, ready to play')

+app = QtWidgets.QApplication([''])
 ad = AudioDecoder()
+
+import signal
+signal.signal(signal.SIGINT, signal.SIG_DFL)
+# press Ctrl+C to exit
+
+app.exec_()

2 个答案:

答案 0 :(得分:1)

Becoz,你有条件规定if语句不要求超过5个。

  

if(concurrent_requests< 5){

此解决方案不具有可伸缩性,因为在某些递归调用之后会覆盖堆栈。

希望它有所帮助。

答案 1 :(得分:1)

  

您正在使用if条件来检查并发计数   请求少于五个或不少。但请记住它是if声明,   不循环。这意味着它只会被调用一次。

     

您正在对您的函数makeApiCall进行递归调用   请求的回调。请求的回调仅运行   当请求得到满足时。

考虑到以上两点,在if条件下,您检查concurrent_requests<5是否调用了请求方法,并且您的程序变得理想。在满足请求id的某个时间之后,请求的回调运行,在一些逻辑再次调用makeApiCall之后。因此,在每次通话中,您只需要拨打一次请求,然后等待解决,然后只有您的程序继续进行下一次请求。

如果您想要并发请求,请使用像这样的循环

function makeApiCall(url){
    if(url) {
        queue.unshift(url);
    }
    // Use a loop here
    while(concurrent_requests<5) {
        var nextUrl = queue.pop();
        if(nextUrl) {
            concurrent_requests++;
            request(nextUrl, function (error, response, body) {
                var invalidUrl;
                concurrent_requests--;
                if(body) {
                        ...
                        if (!invalidUrl) {
                            makeApiCall(url);
                            data += url + ", " + nextUrl + "\n";
                        }
                    }
                    ...
                }
                else{
                    makeApiCall();
                }
            });
        }
        else{
           // Remember to break out of loop when queue is empty to avoid infinite loop.
           break;
        }
    }
     console.log(concurrent_requests);

}