2010-12-15 205 views
1

我有這個js類,它有一個匿名函數來檢索一些查詢結果。由於處理結果的函數是匿名的,我不能將結果保存在this.var變量中,並將它們用在別的地方,因爲這在匿名函數中引用了窗口對象。我不能將它作爲函數返回,所以我如何處理這些結果讓它們在別處可用?Javascript匿名函數問題

someObject = { 
    // this.db is created, no need to paste that code 
    dbGetAnimals: function() { 
     this.db.readTransaction(function(tx) { 
      tx.executeSql("SELECT * FROM animals", function(tx, results){ 
       return results; 
      }) 
     }); 
    }, 
    printAllAnimals: function() { 
     var animals = this.dbGetAnimals(); 
     alert (animals);// undefined 
    } 
} 

someObject.printAllAnimals(); 
+1

dooooont從JavaScript調用發送SQL,這會打開你的攻擊很多。 – 2010-12-15 21:13:37

+0

網絡存儲伴侶。在發佈前學習lol:http://www.html5rocks.com/tutorials/webdatabase/todo/?todo = sddf – 2010-12-15 21:38:23

回答

3

您可以創建一個局部變量來容納您的this參考。你的匿名函數將成爲閉包,所以它將能夠看到本地變量。

dbGetAnimals: function() { 
    var myself = this; 
    this.db.readTransaction(function(tx) { 
     tx.executeSql("SELECT * FROM animals", function(tx, results){ 
      myself.var = results; 
     }) 
    }); 
}, 
+2

這是最簡單的方法。但我認爲這很醜陋。如果我需要在上下文中執行回調,則只需使用lib綁定上下文。如果你不使用庫,這是要走的路。請參閱http://www.prototypejs.org/api/function/bind以獲得對問題的全面描述 – 2010-12-15 21:30:19

0

發生這種情況,因爲executeSql匿名函數是不是直到查詢compmetes,根據定義會後dbGetAnimals返回執行的回調函數。這就是爲什麼你的電話dbGetAnimals返回undefined。

你必須傳遞一個回調函數從executSql回調中接收查詢resutls:

someObject = { 
    // this.db is created, no need to paste that code 
    dbGetAnimals: function (callback) { 
     this.db.readTransaction(function(tx) { 
      tx.executeSql("SELECT * FROM animals", function(tx, results){ 
       callback(results); 
      }); 
     }); 
    }, 
    printAllAnimals: function() { 
     this.dbGetAnimals(function(animals) { 
      alert(animals) 
     }); 
    } 
} 


someObject.printAllAnimals(); 
+0

我得到:Uncaught ReferenceError:動物未定義 – 2010-12-15 21:32:49

+0

@Tim:哦,呵呵。該代碼與您遇到的問題相同 - alert()會在查詢實際運行之前運行。我修正了上面的代碼。 – josh3736 2010-12-15 23:54:07

+0

好的,但這仍然不能保存我的問題。雖然alert()函數可能在該回調函數內部工作,但我無法將「動物」提供給課程的其他成員。如何在調用printAllAnimals時將對象本身內的「動物」返回? – 2010-12-16 02:11:03

2

你正在試圖做的傳統的同步/非阻斷的你想要做的異步編程節目。

var someObject = function()({ 
    this.dbGetAnimals = function (callback) { 
     db.readTransaction(function(tx) { 
      tx.executeSql("SELECT * FROM animals", function(tx, results){ 
       callback(results); 
      }) 
     }); 
    }, 

    this.printAllAnimals = function (callback) { 
     this.dbGetAnimals(callback); 
    } 
})(); 

someObject.printAllAnimals(function(animals) { 
    alert(animals); 
} 

有更清潔的方式來做到這一點,但對於異步編程,你必須學會​​做回調,而不是直接回報的一切。

+0

我會向你解釋我的情況,看看爲什麼這是一個大問題。我正在構建一個包含網格的小型ExtJs應用程序。所以首先我有一個ExtJS窗口,然後我添加一個網格到該窗口。網格要求項目顯示一些東西。有了這種類型的請求和回調麻煩,不可能簡單地返回網格的值來使用它們。我必須創建交易並在交易內部建立窗口和網格。在你的例子中,'動物'仍然被困在'printAllAnimals'的回調函數中。我在http://pastebin.com/3a8GQG8F上創建了一個完整的示例。 – 2010-12-16 20:06:05

+0

您可以將其插入到html頁面中,並使用chrome開發人員工具監視本地存儲。從示例中可以看到,alert(動物)始終返回undefined,因此如何在回調函數外使用該結果? – 2010-12-16 20:07:20