IDBCursor对ajax的成功有不同的价值

IDBCursor has different value on ajax success

本文关键字:成功 ajax IDBCursor      更新时间:2023-09-26

我为我的购物车函数实现了下面的代码。在将整个购物车保存到数据库之前,我使用 IndexedDB 在本地保存产品数据。通过链接进入购物车时,下面的代码执行得很好。但是如果我点击刷新或重新加载它,光标变量的值会有所不同。我在 ajax 请求之前和 ajax 成功时测试了 console.log(cursor.value.pid)。在他们的中,我注意到在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
          )

在最初的示例中,下面是简化伪代码中代码的广泛结构:

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

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

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

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

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

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

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

value变量的新副本将在每次调用 openCursor 请求的成功回调中捕获。

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

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