2012-06-06 31 views
2

我不知道我應該採取什麼樣的途徑來使這個代碼的工作「的預期。」 API調用是異步的 - 所以構造函數在數據加載之前返回。需要異步API調用數據的構造函數?

addSongById: function (songId) { 
    var song = new Song(songId); 
    console.log(song); 
    this.addSong(song); 

    if (this.songCount() == 1) 
     this.play(); 

    UserInterface.refresh(); 
    SongGrid.reload(); 
}, 

function Song(songId) { 
    $.getJSON('http://gdata.youtube.com/feeds/api/videos/' + songId + '?v=2&alt=json-in-script&callback=?', function (data) { 
     this.id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); 
     this.songId = songId; 
     this.url = "http://youtu.be/" + songId; 
     this.name = data.entry.title.$t; 
    }); 
} 

是否有可能強制構造函數不提前返回?理想情況下,我不會要的參數任意量傳遞到宋構造和帶來的只是宋它的範圍之外的相關信息..

回答

3

您可能想要使用$.ajax而不是$.get並使用選項async: false。但是,這將鎖定每個其他JavaScript的執行。如果服務器因任何原因不響應,這可能是個問題。

因此,這是一個不好的做法。使用回調,例如

function Song(songId, callback) { 
    var self = this; 
    $.getJSON('http://gdata.youtube.com/feeds/api/videos/' + songId + '?v=2&alt=json-in-script&callback=?', function (data) { 
     self.id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); 
     self.songId = songId; 
     self.url = "http://youtu.be/" + songId; 
     self.name = data.entry.title.$t; 
     callback(); 
    }); 
} 

var song = new Song(songId, function() { 
    // The other code goes here. 
}); 
+0

我認爲這是我想要的。讓我試試看,一秒鐘。 –

+1

'getJSON'回調中的'this'不會引用'Song'實例。 – lanzz

+0

@lanzz哦,是的。我剛剛複製了代碼。讓我編輯它。 – freakish

0

同步調用可能導致瀏覽器停止響應,一些瀏覽器可能會殺了你的腳本有力地。

Jquery的有一個選項,同時使一個URI

asyncBoolean默認的請求:真

缺省情況下,所有的請求是非同步地發送(即,這是通過默認設置爲 真)。如果您需要同步請求,請將此選項設置爲 false。跨域請求和dataType:「jsonp」請求不支持 同步操作。請注意,同步請求可能會暫時 鎖定瀏覽器,禁用任何行動,同時請求 處於活動狀態。從jQuery 1.8開始,不贊成使用async:false。

http://api.jquery.com/jQuery.ajax/

希望這將有助於

問候。

+0

嗯,我應該擔心使用過時的參數? –

+0

我希望你不使用jquery 1.8,因爲它現在還不穩定。但您可以安全地在1.7.x上使用它。 –

7

與大多數異步操作,我會使用一個Deferred在這種情況下,在JS構造不一定要返回自己的一個實例:

function Song(songId) { 
    var song = this; 
    var def = new $.Deferred(); 
    $.getJSON('http://gdata.youtube.com/feeds/api/videos/' + songId + '?v=2&alt=json-in-script&callback=?', function (data) { 
     song.id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) { var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8); return v.toString(16); }); 
     song.songId = songId; 
     song.url = "http://youtu.be/" + songId; 
     song.name = data.entry.title.$t; 
     def.resolve(song); 
    }); 
    return def.promise(); 
} 

var promise = new Song(songId); 
promise.done(function(instance) { 
    // you've got a Song instance 
}); 
+0

比回調方案更好。 –

+1

很老的線程我知道,但是然後返回承諾,爲什麼不把它存儲在'this.promise = def.promise();'然後在異步回調'def.resolve(this)'?這樣構造函數返回對象,並且回調可以按照這種方式鏈接:'var song = new Song(songId); song.promise.done(function(){doWhatever()})' – undefinederror

+0

@undefinederror是一個很好的觀點。單例構造函數不應該返回任何東西,除了它自己的實例 –

3

...這是一個不好的做法。構造函數應該返回其類的實例,沒有別的。否則它會弄亂新的運營商和繼承。

此外,構造函數應該只創建和初始化一個新的 實例。它應該設置數據結構和所有特定於實例的屬性,但不執行任何任務。這應該是一個純函數 無副作用如果可能的話,使用具有的所有好處。

編號:Is it bad practice to have a constructor function return a Promise?