2016-04-27 51 views
0

我有以下一段JavaScript的地方,我执行一个SQL查询,并根据结果我需要执行第二个查询。虽然我管理使用闭包来为第二个查询迭代适当的值,但我还是无法将所需的值返回。我一直未定义。从封闭返回值给出undefined

 db.transaction(function(tx) { 
      tx.executeSql('SELECT * FROM maintainance', [], function(tx, results){ 
       maintainance_length = results.rows.length; 
       maintanance_query = results.rows; 
       for (i = 0; i < maintanaince_length; i++) { 
        maintainance_title = maintanance_query[i].element; 
        var classAction = function(){ 
         if(maintanance_query[i].code == '0'){ 
          return 'no'; 
         }else{ 
//over here i use the closure to iterate each seperate maintainance_title value 
          (function(maintainance_title){ 
          db.transaction(function(tx) { 
          tx.executeSql('SELECT * from maintainance_history WHERE element = \''+maintainance_title+'\'', 
          [], function(tx, results){ 
           if(results.rows.length > 0 && results.rows[0].action == '1'){ 
            return 'ok'; 
           }else{ 
            return 'warn'; 
           } 
          },function(tx, error){ 
            console.log(error); 
            console.log(tx); 
          });}); 
          })(maintainance_title); 
         } 
        } 
        historyIcon = "<div class=\""+classAction()+"\"></div>"; 
       } 
       },function(tx, error){ 

       } 
      ); 
     }); 

我测试了一些变化OVR部份代码,但仍是结果要么是未捕获的异常的“未定义”那classAction不是一个函数

+1

'classAction()'是一个异步函数,您试图同步调用它。不幸的是,您返回“ok”或“warn”的地方会回到空虚状态,这些返回值并没有真正做到。 'classAction()'底部没有'return',所以它总是返回undefined。 – aaronofleonard

+0

所以,而不是我可以包裹“historyIcon =”

“;”转换成函数,并在每次返回的地方调用它。这样,当每次迭代完成时它会被调用 – nikolas

+0

是的,这是我在我的答案中采取的方法,好的想法;) – aaronofleonard

回答

1

与我的评论一起去,因为classAction是异步,我们必须把它看作一个异步函数。这意味着return走出了窗口!我们可以使用Promise,但这需要更重要的重写。这里是我建议使用回调更简单的重写。这仍然可能无法正常工作,具体取决于您想要用historyIcon做什么。但是historyIcon将被设置为适当的值,并且如果您需要处理它,则可能需要另一个回调。

db.transaction(function(tx) { 
    tx.executeSql('SELECT * FROM maintainance', [], function(tx, results){ 
     maintainance_length = results.rows.length; 
     maintanance_query = results.rows; 

     for (i = 0; i < maintanaince_length; i++) { 
      maintainance_title = maintanance_query[i].element; 

      var classAction = function(callback){ 
       if(maintanance_query[i].code == '0'){ 
        callback('no'); 
       } 
       else { 
        (function(maintainance_title){ 

         db.transaction(function(tx) { 
          tx.executeSql('SELECT * from maintainance_history WHERE element = \''+maintainance_title+'\'', [], 
           function(tx, results){ 
            if(results.rows.length > 0 && results.rows[0].action == '1'){ 
             callback('ok') 
            }else{ 
             callback('warn'); 
            } 
           },function(tx, error){ 
             console.log(error); 
             console.log(tx); 
           }); 
         }); 

        })(maintainance_title); 
       } 
      }; 

      classAction(function(action) { 
       historyIcon = "<div class=\""+action+"\"></div>"; 
      }); 
     } 
    },function(tx, error){ 
     // error stuff 
    }); 
}); 
+0

现在变得更加复杂了,由于异步调用的延迟,只有historyIcons具有动作不会追加到DOM,而不是其他的,因为延迟 – nikolas

+1

@nikolas,好吧,您需要修改操作DOM以异步工作的函数。你固有地不能在异步调用 – aaronofleonard

+0

中使用异步调用的结果,这是真的,我在回调中添加了一个if语句,并在所有期望的回调发生时在dom中插入了所有必需的项目:) – nikolas