- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
所以,过去几天我一直在研究这段代码,并尝试实现回调/等待/任何需要的东西,但没有成功。
问题是,我如何等待响应,直到我得到两个函数的回调? (以及我将如何实现)
简而言之,我想做的是:
getpTracks()
getpTracks()
开始,我们继续使用 dbChecks()
获取每条轨道scrapeUrl()
我用一些时髦的代码对代码进行了创可贴,每 250 毫秒检查一次请求的轨道数量是否与最终数组中的轨道数量匹配。但这并不是我真正想要的,因为如果一次有多个 POST 请求,它就会变得非常糟糕。
当前代码:
app.post("/spotify/playlist", (req, res) => {
pTracks = [];
let playlistId = req.body.id;
t0 = performance.now();
getpTracks(playlistId);
let waitTime = setInterval(waitTillReady, 250);
function waitTillReady() {
counterLoop++;
console.log("a: " + countera + "||" + pTracks.length);
console.log("b: " + counterb + "||" + pTracks.length);
console.log("a + b: " + (countera + counterb) + "||" + pTracks.length);
console.log("Loop: " + counterLoop);
// REPLACE WITH ASYNC OR CALLBACK!!
if (
countera == pTracks.length ||
counterb == pTracks.length ||
countera + counterb == pTracks.length ||
counterLoop == 35 // 75 items scraping took on avg 4.8sec
) {
countera = 0;
counterb = 0;
clearInterval(waitTime);
res.send(pTracks);
t1 = performance.now();
console.log("Call took " + (t1 - t0) + " milliseconds.");
pTracks = [];
}
}
});
function getpTracks(args) {
spotifyApi.getPlaylistTracks(args, { limit: 75 }).then(function(data) {
let temp = data.body.items;
for (let b = 0; b < temp.length; b++) {
let trackName = temp[b].track.name;
for (let e = 0; e < temp[b].track.artists.length; e++) {
var trackArtist = temp[b].track.artists[e].name;
}
dbChecks(trackName, trackArtist);
//let trackId = temp[b].track.id + ",";
//spotifyApi.getAudioFeaturesForTracks([trackId]).then(function(data) { // bpm, key etc
}
});
}
function dbChecks(trackName, trackArtist) {
url = "https://www.songsterr.com/a/wa/bestMatchForQueryString?s=";
//console.log(trackArtist + '|||' + trackName);
//console.log(url)
dbSongsterr
.findOne({ artist: trackArtist, track: trackName }) // get results from mongo
.then(response => {
if (
//if we find results,
response != null &&
response.artist == trackArtist &&
response.track == trackName
) {
countera++;
pTracks.push({
//push them into array
artist: response.artist,
name: response.track,
url: response.url,
tuning: response.tuning
});
} else if (response == null) {
//if no results found, go webscrape
urli = url + trackName + "&a=" + trackArtist; // url constructor
pTracks.push({
artist: trackArtist,
name: trackName,
url: urli
});
scrapeUrl(urli, trackName, trackArtist);
}
})
.catch(error => {
console.log("Error: " + error);
});
}
function scrapeUrl(url, track, artist) {
url = url;
console.log(artist + "|||" + track);
rp({
url: url,
resolveWithFullResponse: true,
transform: function(body) {
return cheerio.load(body);
}
})
.then(async res => {
counterb++;
tempartist = artist.replace(/\s+/g, "");
artistSongsterr = await res(".artist-1u304B") // tab page artist name
.text()
.replace(/\s+/g, "");
//console.log(artistSongsterr);
if (
artistSongsterr != "" &&
artistSongsterr.toLowerCase() == tempartist.toLowerCase()
) {
// maybe add check for song aswell
tuning = res(".tuning-1cQdvc").text(); // tab page tuning
//console.log(tuning);
if (tuning != "") {
for (let y = 0; y < pTracks.length; y++) {
if (pTracks[y].name == track && pTracks[y].tuning == null) {
pTracks[y] = { ...pTracks[y], ...{ tuning: tuning } };
dbSongsterr.insert({
artist: artist,
track: track,
url: url,
tuning: tuning
});
}
}
}
} else {
dbSongsterr.insert({
// if didnt pass artist name check then
artist: artist,
track: track,
url: false,
tuning: false
});
//console.log('Artist check fail')
}
})
.catch(err => {
counterb++;
console.log("Site crawl fail");
pTracks.push({
artist: track,
name: track,
url: false,
tuning: false
});
dbSongsterr.insert({
artist: artist,
track: track,
url: false,
tuning: false
});
});
}
最佳答案
一些一般性建议:
您通常不需要全局变量(因此正确声明它们),如果变量应该在多个函数之间共享并显式传递它们,则函数应该返回它们产生的结果。
不要将 .then
链与 await
混合使用,它看起来很难看,令人困惑,并且可能会引入微妙的错误。
也就是说你的函数应该是异步的:
async function scrapeUrl(url, track, artist, result = []) {
console.log(artist + "|||" + track);
try {
const res = await rp({
url,
resolveWithFullResponse: true,
transform: function(body) {
return cheerio.load(body);
},
});
const tempartist = artist.replace(/\s+/g, "");
const artistSongsterr = await res(".artist-1u304B") // tab page artist name
.text()
.replace(/\s+/g, "");
if (artistSongsterr && artistSongsterr.toLowerCase() == tempartist.toLowerCase()) {
// maybe add check for song aswell
const tuning = res(".tuning-1cQdvc").text(); // tab page tuning
if (tuning) {
for (const el of pTracks) {
if (el.name == track && !el.tuning) {
el.tuning = tuning;
result.push({ url, track, artist, tuning });
}
}
}
} else {
result.push({
// if didnt pass artist name check then
artist,
track,
url: false,
tuning: false
});
//console.log('Artist check fail')
}
}
} catch(error) {
console.log("Site crawl fail");
result.push({
artist: track,
name: track,
url: false,
tuning: false
});
}
return result;
}
async function dbChecks(trackName, trackArtist, result = []) {
const url = "https://www.songsterr.com/a/wa/bestMatchForQueryString?s=";
try {
const response = await dbSongsterr
.findOne({ artist: trackArtist, track: trackName }) // get results from mongo
if (
//if we find results,
response &&
response.artist == trackArtist &&
response.track == trackName
) {
result.push({
//push them into array
artist: response.artist,
name: response.track,
url: response.url,
tuning: response.tuning
});
} else {
//if no results found, go webscrape
const urli = url + trackName + "&a=" + trackArtist; // url constructor
result.push({
artist: trackArtist,
name: trackName,
url: urli
});
await scrapeUrl(urli, trackName, trackArtist, result);
}
} catch(error) {
console.log("Error: " + error);
}
return result;
}
async function getpTracks(args) {
const result = [];
const data = await spotifyApi.getPlaylistTracks(args, { limit: 75 });
let temp = data.body.items;
for (const { track: { name: trackName, artists }} of temp) {
const trackArtist = artists[artists.length - 1].name;
// TODO: use Promise.all to parallelize
await dbChecks(trackName, trackArtist, result);
}
return result;
}
可以在端点中使用:
app.post("/spotify/playlist", async (req, res) => {
res.send(await getpTracks(req.body.id));
});
关于javascript - 如何在我的代码中实现回调/等待?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52557360/
背景: 我最近一直在使用 JPA,我为相当大的关系数据库项目生成持久层的轻松程度给我留下了深刻的印象。 我们公司使用大量非 SQL 数据库,特别是面向列的数据库。我对可能对这些数据库使用 JPA 有一
我已经在我的 maven pom 中添加了这些构建配置,因为我希望将 Apache Solr 依赖项与 Jar 捆绑在一起。否则我得到了 SolarServerException: ClassNotF
interface ITurtle { void Fight(); void EatPizza(); } interface ILeonardo : ITurtle {
我希望可用于 Java 的对象/关系映射 (ORM) 工具之一能够满足这些要求: 使用 JPA 或 native SQL 查询获取大量行并将其作为实体对象返回。 允许在行(实体)中进行迭代,并在对当前
好像没有,因为我有实现From for 的代码, 我可以转换 A到 B与 .into() , 但同样的事情不适用于 Vec .into()一个Vec . 要么我搞砸了阻止实现派生的事情,要么这不应该发
在 C# 中,如果 A 实现 IX 并且 B 继承自 A ,是否必然遵循 B 实现 IX?如果是,是因为 LSP 吗?之间有什么区别吗: 1. Interface IX; Class A : IX;
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用资料或专业知识的支持,但这个问题可能会引发辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the
我正在阅读标准haskell库的(^)的实现代码: (^) :: (Num a, Integral b) => a -> b -> a x0 ^ y0 | y0 a -> b ->a expo x0
我将把国际象棋游戏表示为 C++ 结构。我认为,最好的选择是树结构(因为在每个深度我们都有几个可能的移动)。 这是一个好的方法吗? struct TreeElement{ SomeMoveType
我正在为用户名数据库实现字符串匹配算法。我的方法采用现有的用户名数据库和用户想要的新用户名,然后检查用户名是否已被占用。如果采用该方法,则该方法应该返回带有数据库中未采用的数字的用户名。 例子: “贾
我正在尝试实现 Breadth-first search algorithm , 为了找到两个顶点之间的最短距离。我开发了一个 Queue 对象来保存和检索对象,并且我有一个二维数组来保存两个给定顶点
我目前正在 ika 中开发我的 Python 游戏,它使用 python 2.5 我决定为 AI 使用 A* 寻路。然而,我发现它对我的需要来说太慢了(3-4 个敌人可能会落后于游戏,但我想供应 4-
我正在寻找 Kademlia 的开源实现C/C++ 中的分布式哈希表。它必须是轻量级和跨平台的(win/linux/mac)。 它必须能够将信息发布到 DHT 并检索它。 最佳答案 OpenDHT是
我在一本书中读到这一行:-“当我们要求 C++ 实现运行程序时,它会通过调用此函数来实现。” 而且我想知道“C++ 实现”是什么意思或具体是什么。帮忙!? 最佳答案 “C++ 实现”是指编译器加上链接
我正在尝试使用分支定界的 C++ 实现这个背包问题。此网站上有一个 Java 版本:Implementing branch and bound for knapsack 我试图让我的 C++ 版本打印
在很多情况下,我需要在 C# 中访问合适的哈希算法,从重写 GetHashCode 到对数据执行快速比较/查找。 我发现 FNV 哈希是一种非常简单/好/快速的哈希算法。但是,我从未见过 C# 实现的
目录 LRU缓存替换策略 核心思想 不适用场景 算法基本实现 算法优化
1. 绪论 在前面文章中提到 空间直角坐标系相互转换 ,测绘坐标转换时,一般涉及到的情况是:两个直角坐标系的小角度转换。这个就是我们经常在测绘数据处理中,WGS-84坐标系、54北京坐标系
在软件开发过程中,有时候我们需要定时地检查数据库中的数据,并在发现新增数据时触发一个动作。为了实现这个需求,我们在 .Net 7 下进行一次简单的演示. PeriodicTimer .
二分查找 二分查找算法,说白了就是在有序的数组里面给予一个存在数组里面的值key,然后将其先和数组中间的比较,如果key大于中间值,进行下一次mid后面的比较,直到找到相等的,就可以得到它的位置。
我是一名优秀的程序员,十分优秀!