2013-07-22 23 views
0

我在调用一个将编辑保存到数据库的函数,并返回dojo/Deferred。我发现我无法一次保存所有记录,所以我限制每次只能发送150条记录,而只需使用for循环将几个呼叫连接在一起。带数组覆盖参数的Dojo延期链接

每次运行此代码时,前150条记录都会成功保存,最后一批记录将成功保存。任何批次之间似乎都被最终批次覆盖。

下面是代码:

applyEdits : function(layer, adds, updates, deletes, editInterval) { 

    adds = adds || []; 
    updates = updates || []; 
    deletes = deletes || []; 

    var maxFeatures = Math.max(adds.length, updates.length, deletes.length); 

    var editInterval = editInterval || 155; 

    var deferred = new Deferred(); 
    deferred.resolve(); 

    for (var i = 0; i < maxFeatures; i+=editInterval) { 

     var addGroup = adds.slice(i, i+editInterval); 
     var updateGroup = updates.slice(i, i+editInterval); 
     var deleteGroup = deletes.slice(i, i+editInterval); 

     deferred = deferred.then(lang.hitch(this, function() { 
      return layer.applyEdits(addGroup, updateGroup, deleteGroup).then(function() { 
       console.log("success"); 
      }, function(error) { 
       console.log(error); 
      }); 
     })); 
    } 

    return deferred; 

addsupdatesdeletes是一切都Array '的Object S'。我的猜测是,因为Array的存储引用,每次通过循环覆盖引用。我试图在将它们传递给layer.applyEdits之前创建Array的深度副本,但这没有任何效果。

+0

看一看[使用Javascript封闭内循环 - 简单实用的例子( http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example)。你喜欢你需要通过'lang.hitch'保存这个'',你需要保留'addGroup','updateGroup'和'deleteGroup'变量。 – Bergi

+0

@Bergi - 谢谢你指点我那个帖子。但是,我无法直接将该帖子中的解决方案应用于我的情况。另一方面,基于您对'lang.hitch'的评论,我可以通过将'addGroup','updateGroup'和'deleteGroup'作为参数传递给'lang.hitch'来获得我的代码。我同意我的问题涉及到您提供的其他帖子的类似主题,但我不会说它是重复的。如果您想根据您的评论提供我的问题的答案,请这样做。 – Brian

回答

0

引用被每次覆写通过循环

完全正确。不是因为它们是对数组的引用,只是因为它们是被覆盖的变量中的值。有关计数器变量i被覆盖的示例,请检查JavaScript closure inside loops – simple practical example。当循环运行后执行延迟回调(因为它们是异步的),变量将只保存最后分配的值,即最后一次迭代中的值。

为了解决这个问题,使用闭包:

for (var i = 0; i < maxFeatures; i+=editInterval) (function() { 
    var addGroup = adds.slice(i, i+editInterval); 
    var updateGroup = updates.slice(i, i+editInterval); 
    var deleteGroup = deletes.slice(i, i+editInterval); 

    deferred = deferred.then(lang.hitch(this, function() { 
     return layer.applyEdits(addGroup, updateGroup, deleteGroup).then(function() { 
      console.log("success"); 
     }, function(error) { 
      console.log(error); 
     }); 
    })); 
})(); 

它更优雅的使用封闭了值作为closure函数的参数,从外部通过他们。在你的情况,你甚至可以直接bind它们的回调函数(或使用Dojo的lang.hitch旧的浏览器,其做同样的事情):

for (var i = 0; i < maxFeatures; i+=editInterval) 
    deferred = deferred.then(function(addGroup, updateGroup, deleteGroup) { 
     return layer.applyEdits(addGroup, updateGroup, deleteGroup).then(function() { 
      console.log("success"); 
     }, function(error) { 
      console.log(error); 
     }); 
    }.bind(this, adds.slice(i, i+editInterval), updates.slice(i, i+editInterval), deletes.slice(i, i+editInterval)));