0

例子:

有 2 行的数据库表:

 rowid name qty date   
 1     milk   3 8/25    
 2     milk  40 8/30    

需要先使用最旧的牛奶执行减去 5 个牛奶项目的库存交易。

例如

选择 rowid 1 等待其回调,并在其中删除 rowid 1,因为它的数量变为 0 并因此被花费

新删除 qty = 5 - 3 = 2。由于不是 0,所以需要再做一个 Select。

选择rowid 2

等待它的回调并在其中更新 rowid 2 以设置 qty = 38。

sqlite 绑定中的序列化功能只会序列化两个 Select。在第一个 Select 及其回调完成之前,甚至无法知道第二个 Select 是否需要。直到那时它才意识到第一个 Select 提供的数量不足。

如何使用纯 JavaScript 序列化第一个 Select 及其回调 - 没有 JQuery 或其他库。

这是一个伪代码示例:这是我能想到的用于演示该问题的最小示例。

假设 db 是一个成功的 sqlite 数据库打开调用的结果。

var deletionQty = 5;

function selectCallBack(error, row) {
   // Assume no error.
   if (deletionQty >= row.qty) {
      // Delete row.rowNum
      deletionQty -= row.qty;   // Need to get the next table row to deduct remaining inventory from it.
   } else {
      // Update row.rowNum -> set qty = qty - deletionQty
      deletionQty = 0;          // Done!
   }
}

while (deletionQty > 0) {
   db.get("SELECT rowid AS rowNum, qty FROM Inventory ORDER BY date LIMIT 1", selectCallBack);
}

问题是 while 将连续执行,因为在其范围内没有任何内容会更改 deleteQty 的值。只有回调会修改它,因为这些是异步事件,所以 while 循环将执行 100 次,然后回调会更改 deleteQty 的值。如果存在 1 对 1 关系(同步关系),因此只执行一个 db.get,然后在下一个 while 循环之前执行其回调,一切都会正常工作。这是异步延迟回调,它允许 while 连续执行设置新的回调,这就是问题所在。

4

1 回答 1

0

I've recently created a simple abstraction named WaitFor to call async functions in sync mode (based on Fibers): https://github.com/luciotato/waitfor

your code with wait.for:

...in a fiber...
var deletionQty = 5;
while (deletionQty > 0) {
   var data= wait.forMethod(db,'get',"SELECT rowid AS rowNum, qty FROM Inventory ORDER BY date LIMIT 1");
   if (deletionQty >= data.qty) {
      // Delete row.rowNum
      wait.forMethod(db,'delete', data.id);
      deletionQty -= data.qty;   // Need to get the next table row to deduct remaining inventory from it.
   } else {
      // Update row.rowNum -> set qty = qty - deletionQty
      wait.forMethod(db,'update'...
      deletionQty = 0;          // Done!
   }

}//loop

WiredPrairie's comment it's the most accurate. You can't turn off async in Node. It's fundamental to Node. You need a lib like wait.for(based on node-fibers), or 'async' or promises (Q) to code sequential logic.

DB sequential logic it's not what's node is made for.

check this answer also: Callback hell in nodejs?

Beyond all this, maybe you need to have a table with: product_id, qyt_in_stock and increment or decrement this field instead of deleting and inserting rows.

于 2013-09-01T15:48:03.897 回答