我正在编写一个Javascript函数,它将单词从CloudDB数据库中提取出来,并将它们放在三个数组中的一个中:动词,形容词或名词。一旦所有单词都到位并且最后一个循环运行,我想运行下一个函数。这是代码:
function verbnoun(array){
verbs = [];
adjectives = [];
nouns = [];
for (i = 0; i<array.length; i++){
//console.log(i); <-- returns 0,1,2,3...57,58 as expected
my_db.get(array[i], function(err, doc) {
if (!err){
if (doc.type == "verb"){
verbs.push(doc.word);
}
else if (doc.type == "adjective"){
adjectives.push(doc.word);
}
else if (doc.type == "noun"){
nouns.push(doc.word);
}
}
//console.log(i); <-- returns 59,59,59,59,59
if (i+1 == array.length){
nextFunction(verbs, adjectives, nouns);
}
});
}
}
但是我无法弄清楚如何在最后一个循环之后运行下一个函数。如果我尝试在for循环之外运行它,我只是得到空数组。使用if语句在最后一个循环上触发似乎也不起作用,因为&#34; i&#34;在for循环中每次都停留在59,而不是从0,1,2,3等开始计数(参见代码中的注释),所以我不能指出哪个是最后一个循环。
这是我在StackExchange上的第一篇文章,感谢您的耐心等待。
答案 0 :(得分:2)
你正在遭遇def main():
global Thread
app = QtGui.QApplication(sys.argv)
main = Main()
Thread = RFID_Thread()
Thread.rfid_event.connect(Main().on_event)
Thread.start()
sys.exit(app.exec_())
class Main(object):
def __init__(self):
self.accueil = MainWindow(self)
self.access = AccessWindow()
self.accueil.show()
def on_event(self, data):
# I WANT TO PAUSE THE QTHREAD HERE
Thread.Pause = False
###################################
# CHECKING DB & SHOWING UI #
###################################
# AND RESUME IT HERE
Thread.Pause = True
class RFID_Thread(QtCore.QThread):
rfid_event = pyqtSignal(str, name='rfid_event')
Pause = True
def run(self):
while 1:
if Pause:
ser = serial.Serial(port=Serial_Port, baudrate=Serial_Baudrate)
a = ser.read(19).encode('hex')
ser.close()
if len(a) <> 0:
Code = a[14:]
self.rfid_event.emit(Code)
time.sleep(2)
else:
continue
if __name__=='__main__':
main()
的关闭,在i
个任何一个get
来电之前,它已经(可能)一直增加到59,并触发了他们的回调。
基本上,i
表示发送的请求数,而不是已成功返回的请求数。您需要一个不同的计数器来跟踪该值。
function verbnoun(array) {
verbs = [];
adjectives = [];
nouns = [];
// New counter for completed requests
var finished = 0;
for (i = 0; i < array.length; i++) {
//console.log(i); <-- returns 1,2,3...57,58,59 as expected
my_db.get(array[i], function(err, doc) {
if (!err) {
if (doc.type == "verb") {
verbs.push(doc.word);
} else if (doc.type == "adjective") {
adjectives.push(doc.word);
} else if (doc.type == "noun") {
nouns.push(doc.word);
}
}
//console.log(i); <-- returns 59,59,59,59,59
if (++finished == array.length) {
nextFunction(verbs, adjectives, nouns);
}
});
}
}
&#13;
答案 1 :(得分:1)
你在那里遇到两个(或可能是三个)问题:
for
循环之后无法执行此操作的原因是get
对数据库的调用还没有完成;他们是异步的。事实上,重要的是要记住,您的函数将在>强的第一个get
返回之前返回。
i
的回调中的 get
是变量i
的持久引用,而不是回调时的副本创建,这就是为什么你看到它总是59(数组长度)。
您的代码因未声明您的本地变量而成为The Horror of Implicit Globals的牺牲品。
请参阅有关如何解决该问题的评论:
function verbnoun(array) {
// Use var to declare your variables
var verbs = [];
var adjectives = [];
var nouns = [];
// Use a counter to remember how many responses you've had
var responses = 0;
// Schedule the calls
for (var i = 0; i < array.length; i++) {
// Call a function do do the work, passing in the index
// for this loop
doGet(i);
}
// Remember, your function returns at this point, before ANY
// of the callbacks occurs
// This function does the work
function doGet(index) {
// Because we're using `index`, not `i`, we get a value
// for each call that won't change
my_db.get(array[index], function(err, doc) {
if (!err) {
if (doc.type == "verb") {
verbs.push(doc.word);
} else if (doc.type == "adjective") {
adjectives.push(doc.word);
} else if (doc.type == "noun") {
nouns.push(doc.word);
}
}
// Count this response
++responses;
// If we have all of them, we're done
if (responses == array.length) {
nextFunction(verbs, adjectives, nouns);
}
});
}
}
虽然实际上,在这种特殊情况下,我们在回调中不需要index
,因此我们并不需要将调用分离为构建函数。但它仍然可以很好地分清所发生的事情。