我创建了一个函数,它将从我的DB返回字符串"path".
function getAudio(mid, cb) {
//mid is an array containing the id to some multimedia files.
for(i=0; i < mid.length; i++) {
db.transaction(function(tx) {
tx.executeSql('SELECT * FROM Multimedia WHERE Mid=' + mid[i] + ' AND Type=' + 2, [], function(tx, results) {
//type=2 is audio. (type=1 is picture file etc) There is only one audiofile in the array.
if(results.rows.length > 0) {
path = results.rows.item(0).Path;
cb(path);
}
}, errorCB);
}, errorCBQuery);
}//end for
}//end getAudio()
Run Code Online (Sandbox Code Playgroud)
当我删除for循环时,查询成功,当for循环在那里时,调用errorCBQuery或errorCB.
有想法该怎么解决这个吗?谢谢 :)
这是经典的闭包问题.transaction
是一个异步调用,这意味着你的循环在你传入的函数被触发之前完成.该函数具有对变量的持久引用i
,而不是您调用时的副本transaction
.因此,每个这样的功能(你生成一个在每次循环)被看到i == mid.length
,因此mid[i]
是undefined
和你的SQL被搞砸.
你需要做的是让回调关闭另一个变量,这个变量在循环进行时不会改变.通常的方法是使用工厂功能:
function getAudio(mid, cb) {
//mid is an array containing the id to some multimedia files.
for(i=0; i < mid.length; i++) {
db.transaction(makeTx(mid[i]), errorCBQuery);
}//end for
function makeTx(val) {
return function(tx) {
tx.executeSql('SELECT * FROM Multimedia WHERE Mid=' + val + ' AND Type=' + 2, [], function(tx, results) {
//type=2 is audio. (type=1 is picture file etc) There is only one audiofile in the array.
if(results.rows.length > 0) {
path = results.rows.item(0).Path;
cb(path);
}
}, errorCB);
};
}
}//end getAudio()
Run Code Online (Sandbox Code Playgroud)
在那里,我传递mid[i]
到makeTx
函数,返回,将获得传递给函数transaction
.我们返回的函数关闭了创建它val
的调用的参数makeTx
,它不会改变.
这是对代码的最小重写; 你可以更进一步.例如,请参阅missingno对问题参数化语句的评论.
旁注:它看起来不像你声明i
或path
任何地方.如果这是真的,你就会成为隐形全球恐怖的牺牲品.建议宣布它们.
归档时间: |
|
查看次数: |
3097 次 |
最近记录: |