IDBCursor 在 ajax 成功时有不同的价值

IDBCursor has different value on ajax success

我为我的购物车功能实现了以下代码。在将整个购物车保存到数据库之前,我使用 IndexedDB 在本地保存产品数据。通过 link 进入购物车时,下面的代码执行得非常好。但是如果我点击刷新或重新加载它,光标变量的值是不同的。我在 ajax 请求之前测试 console.log(cursor.value.pid) 并在 ajax 成功时测试。在他们的文章中,我注意到在 ajax 请求之前,光标的值仍然正确,但在 ajax 请求成功后,它会更改为最后一个产品并根据我在购物车中的商品数量复制该产品.顺便说一句,我使用 ajax 请求从 API 获取数据以进行货币转换。

if $('#shopping-cart').length > 0
  request = indexedDB.open('indexedDB', parseInt(1))
  request.onsuccess = (event)->
    db = event.target.result
    objectStore = db.transaction('cart').objectStore('userCart')
    objectStore.openCursor().onsuccess = (event)->
      cursor = event.target.result
      if cursor
        if cursor.value.disPercent > 0
          discounted = parseFloat(cursor.value.price) - (parseFloat(cursor.value.price) * (parseInt(cursor.value.disPercent) / 100))
          $.ajax(
            url: 'api-xxxx'
            dataType: 'json'
            success: (data)->
              if typeof fx != 'undefined' && fx.rates
                fx.rates = data.rates
                currency = $('body').data('to').toUpperCase()
                price = fx(discounted).from(cursor.value.from.toUpperCase()).to(currency)
                $('#shopping-cart-table-body').append(cursor.value.pid)
                                    createOptions cursor.value.pid, cursor.value.inStock, cursor.value.quantity

          )
        else
          $.ajax(
            url: 'api-xxxx'
            dataType: 'json'
            success: (data)->
              if typeof fx != 'undefined' && fx.rates
                fx.rates = data.rates
                currency = $('body').data('to').toUpperCase()
                price = fx(cursor.value.price).from(cursor.value.from.toUpperCase()).to(currency)
                $('#shopping-cart-table-body').append(cursor.value.pid)
                createOptions cursor.value.pid, cursor.value.inStock, cursor.value.quantity
          )
        cursor.continue()

    )

更新: 我注意到它只是在 ajax 回调中。如果我在第 4 级使用游标值,它会给我同样的问题。例如:

 if $('#shopping-cart').length > 0
  request = indexedDB.open('indexedDB', parseInt(1))
  request.onsuccess = (event)->
    db = event.target.result
    objectStore = db.transaction('cart').objectStore('userCart')
    objectStore.openCursor().onsuccess = (event)->
      cursor = event.target.result
      if cursor
        if cursor.value.disPercent > 0
          // value is still ok in here
          console.log cursor.value.pid
          $.ajax(
            url: 'api-xxxx'
            dataType: 'json'
            success: (data)->
              $('#remove').on('click', ->
                //value of cursor is already different from the above console.log
                console.log cursor.value.pid
          )

初步猜测,但看起来您正在将两个独立的异步事物混合在一起(ajax 和索引数据库调用)。我认为这不像您希望的那样工作。您不能执行一个请求,执行一个 ajax 调用,然后再执行另一个请求,并且让它按照您想要的方式工作。回调将在它们自己的时间轴上发生,而不是按照您正在尝试的类似串行的回调顺序。

当然,这只是一个猜测。我可能完全不喜欢这个。

在您的初始示例中,以下是简化伪代码中代码的大致结构:

openCursor
  if cursor
    console.log(cursor.value)
    ajax
      console.log(cursor.value)
    cursor.continue()

现在添加数字来演示所有内容的顺序 运行 in:

1 openCursor
2  if cursor
3    console.log(cursor.value)
4    ajax
6      console.log(cursor.value)
5    cursor.continue()

请注意,continue() 调用(#5)发生在异步 ajax 回调(#6)之前。到您的 ajax 回调 运行 时,它可能已经前进到下一条记录。

这适用于您的第一个示例。您更新的示例根本没有 cursor.continue() - 它只是没有生成代码段吗?

请注意,一个明显的修复 - 将 continue() 调用移动到 ajax 回调中 - 将不起作用,因为如果没有安排工作,IDB 事务将自动提交。根据您的情况,您可能只能在本地捕获游标值,例如:

openCursor
  if cursor
    console.log(cursor.value)
    value = cursor.value
    ajax
      console.log(value)
    cursor.continue()

每次调用 openCursor 请求的成功回调时,都会捕获 value 变量的新副本。