Javascript 使用prototype向函数添加属性会导致函数参数未定义

Javascript 使用prototype向函数添加属性会导致函数参数未定义,javascript,sqlite,callback,prototype,Javascript,Sqlite,Callback,Prototype,我有一个执行数据库调用(sqlite3)的循环,以减少回调中的库存。它工作得很好,将“使用的部分”减少了1 平均可能有1到60个数组元素,因此此循环将快速连续创建1到60个异步任务。回调函数签名是(error,row),由绑定到sqlite3的JS确定。我不能改变它 i = 0; while (i < struct.PortionsUsed.length) { portionUsed = struct.PortionsUsed[i]; D

我有一个执行数据库调用(sqlite3)的循环,以减少回调中的库存。它工作得很好,将“使用的部分”减少了1

平均可能有1到60个数组元素,因此此循环将快速连续创建1到60个异步任务。回调函数签名是(error,row),由绑定到sqlite3的JS确定。我不能改变它

     i = 0;
     while (i < struct.PortionsUsed.length) {
        portionUsed = struct.PortionsUsed[i];
        Db.get("SELECT blah blah WHERE portion = ? ORDER BY date LIMIT 1", portionUsed, selectCallBack);
        i++;
     }
关闭输出:

   Starting Select for Coffee - count=5
   Starting Select for Hot Tea - count=2
   Hit selectCallBack. count=2 portionUsed=Hot Tea
   objectobject
   Hit selectCallBack. count=2 portionUsed=Hot Tea
   objectobject
原型方法输出:

   Starting Select for Coffee - count=5
   Hit selectCallBack. count=5 portionUsed=Coffee
   undefinedundefined
   selectCallBack error:
   undefined
   Starting Select for Hot Tea - count=2
   Hit selectCallBack. count=2 portionUsed=Hot Tea
   undefinedundefined
   selectCallBack error:
   undefined

在JavaScript中创建新变量作用域的唯一方法是调用函数,这一事实使您的闭包尝试受到影响。在循环中创建函数时,所有函数都在同一变量范围内创建

为了解决这个问题,您需要在循环的每次迭代中调用一个函数,传入需要保存在该新变量范围内的值,并在该范围内创建回调函数。这样,在循环中创建的每个函数都在一个唯一的函数作用域中创建

IMO实现这一点最清晰的方法是将需要作用域的代码移动到一个新函数中,并在循环中调用它

 struct.PortionsUsed = struct.PortionsUsed.sort();
 i = 0;
 while (i < struct.PortionsUsed.length) {
    j = i + 1;
    while (j < struct.PortionsUsed.length && struct.PortionsUsed[i] === struct.PortionsUsed[j]) {
       ++j;
    }
    count = j - i;
    portionUsed = struct.PortionsUsed[i];
    if (debug) {console.log('Starting Select for ' + portionUsed + ' - count=' + count);}

    setHandler(Db, count, portionUsed, selectCallback);

    i = j;
 }

function setHandler(Db, count, portionUsed, callback) {
    // In here, any of the above parameters can be used within the 
    //    handler function created below.
    Db.get("SELECT rowid AS rowNum, portion, qty FROM Portion WHERE portion = ? ORDER BY date LIMIT 1", 
           portionUsed, 
           function(error, row) {
               console.log(count, portionUsed); // Not sure how you wanted to use these
               callback(error, row);
           }
    );
}
struct.PortionsUsed=struct.PortionsUsed.sort();
i=0;
while(i