我怀疑我从根本上误解了Javascript承诺,有什么想法吗?
我有一个漂亮的函数,可以查询包含如下所示音乐的数据库:
function searchDatabaseForTrack(query,loadedResults){
loadedResults = loadedResults || [];
desiredResults = 100;
if (loadedResults.length < desiredResults) {
try {
databaseApi.searchTracks(query, {"offset":loadedResults.length, "limit":"50", }).then(function(data){
i=0
if (data.tracks.items.length == 0) {
console.log(`Already loaded all ${loadedResults.length} tracks!`)
console.log(loadedResults)
return loadedResults;
}
else {
for (thing in data.tracks.items){
loadedResults.push(data.tracks.items[i]);
i=i+1;
}
console.log(loadedResults.length, " tracks collected");
searchDatabaseForTrack(query,loadedResults)
}
});
} catch(err) {
console.log("ERROR!", err)
console.log(loadedResults)
return loadedResults;
}
} else {
console.log(loadedResults)
return loadedResults;
}
}
然后稍后,我尝试调用并使用检索到的数据。
function getArtistTracks(artistName){
searchDatabaseForTrack(artistName).then(function(data){
console.log(songs);
songs.sort(function(a,b){
var c = new Date(a.track.album.release_date);
var d = new Date(b.track.album.release_date);
return d-c;
});
console.log("songs", songs);
var newsongs=[];
i=0
for (song in songs) {
newsongs.push(songs[i].track.uri);
i++
};
return newsongs;
});
}
我要做的是获取第二个函数“ getArtistTracks”,以等待第一个函数中的查询完成。现在我可以直接调用databaseApi.searchTracks了,但是每个结果最多只能返回50条轨道,这让我不知所措。
答案 0 :(得分:0)
searchDatabaseForTrack().then(...)
不起作用,因为searchDatabaseForTrack()
不返回承诺,因此您可以return a promise或使用async函数。
代替递归函数,您只需在databaseApi
循环中调用for
,
desiredResult
应该是一个参数,而不是硬编码在函数中,
async function searchDatabaseForTrack(query, desiredResults){
let loadedResults = [], data, currOffset = 0;
const iterations = Math.ceil(desiredResults / 50);
for(let n = 0 ; n < iterations; n++){
cuurOffset = n * 50;
data = await databaseApi.searchTracks(query, {"offset":currOffset, "limit":"50", });
if (data.tracks.items.length == 0) {
console.log(`Already loaded all ${loadedResults.length} tracks!`)
console.log(loadedResults)
return loadedResults;
}
else {
loadedResults = loadedResults.concat(data.tracks.items);
console.log(loadedResults.length, " tracks collected");
}
}
return loadedResults;
}
只要您添加.catch()
来处理错误(如上一个答案中提到的),这些错误就可以了,而这些错误无需try/catch
块会自动抛出:
function getArtistTracks(artistName, 100){
searchDatabaseForTrack(artistName).then((songs) => {
// your previous code
})
.catch((err) => {
// handle error
});
});
答案 1 :(得分:-1)
获取所有结果后,请incRow < numLines - 1
使用searchDatabaseForTrack
返回Promise.all
。另外,请确保不要像使用loadedResults
那样隐式创建全局变量。例如,尝试以下操作:
thing
和
async function searchDatabaseForTrack(query) {
const desiredResults = 100;
const trackPromises = Array.from(
({ length: Math.ceil(desiredResults / 50) }),
(_, i) => {
const offset = i * 50;
return databaseApi.searchTracks(query, { offset, limit: 50 });
}
);
const itemChunks = await Promise.all(trackPromises);
const loadedResults = itemChunks.reduce((a, { tracks: { items }}) => (
[...a, ...items]
), []);
return loadedResults;
};