IDBCursor对ajax成功有不同的价值

时间:2016-02-22 23:40:43

标签: javascript jquery ajax coffeescript indexeddb

我为我的购物车功能实施了以下代码。在将整个购物车保存在数据库之前,我使用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
          )

2 个答案:

答案 0 :(得分:2)

在您的初始示例中,这里是您的代码在简化伪代码中的广泛结构:

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()调用(#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变量的新副本。

答案 1 :(得分:0)

首先猜测,但看起来你将两个独立的异步事物混合在一起(ajax和索引的db调用)。我认为这不像你想要的那样有效。你不能做一个请求,做一个ajax调用,然后做另一个请求,并让它像你想要的那样工作。回调将在他们自己的时间轴上发生,而不是在您尝试的类似串行的回调顺序中。

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