javascript - 获取多个异步 url 数据,然后对结果进行操作(tampermonkey 脚本)
问题描述
我对JS有点陌生,所以请耐心等待。我正在尝试为网站创建 Tampermonkey (greasyfork) 脚本。
步骤应该是:
- 检查用户是否登录
- 如果是,转到他的“电影评分”页面并加载所有(例如 40 个)页面,获取它们的 HTML,提取电影评分并将它们存储在 LocalStorage
- 完成后,继续执行另一个代码(将列添加到表等...)
现在它可以工作,但它是同步的。因此,当数据不在 LocalStorage 中时,它会非常缓慢地加载每个页面(1page +- 1 秒,典型的是 50-100 页)并且用户等待并且不知道是否发生了任何事情。我的“弹出”功能不适用于“async:false”,但适用于“async:true”。
但是当我使用异步时,它不会等待,并且代码的行为不像我希望的那样。
如果你告诉我“只做一个承诺,只做一个回调”,我不知道该怎么做。我用谷歌搜索了一天,没有找到任何有效的方法。
我通过工作代码示例/修改来学习。
我现在的代码(简化)
(() => {
class Csfd {
constructor(csfdPage) {
this.csfdPage = csfdPage;
this.stars = {}; // dict which is then saved as json to LocalStorage
this.userUrl = undefined;
}
getCurrentUser() { ... }
addRatingsColumn() { ... }
REFRESH_RATINGS() {
// Load user ratings...
$.ajax({
type: "GET",
url: this.userRatingsUrl, // page when pagination of all ratings starts
async: false
}).done((data) => {
this.processRatingsPage(data);
});
}
processRatingsPage(dataHTML) {
var $stars = this.stars;
$(dataHTML).find("tbody tr").each(function () {
let starsRatings .... // simplified line, get the data of each rating row
$stars[filmURL] = starsRating;
});
// Check if there is next page
let nextPaginationURL = $(dataHTML).find("a.page-next").attr("href");
if (nextPaginationURL) {
// Next page exists, fetch it and repeat, add new ratings to `this.stars`
this.loadPage(nextPaginationURL);
} else {
// No next page, finish...
this.finishRefresh();
}
}
loadPage(url) {
let foundMatch = url.match(new RegExp("page=(.*)$"));
let currentNum = 1;
if (foundMatch.length == 2) {
currentNum = foundMatch[1];
}
console.log(`${SCRIPTNAME} - Loading... ${currentNum}/${this.endPageNum}`);
$.ajax({
type: "GET",
url: url,
async: false
}).done((data) => {
this.processRatingsPage(data);
});
}
finishRefresh() {
this.exportRatings(); // export JSON stringify to LocalStorage
}
}
// SCRIPT START
csfd.userUrl = csfd.getCurrentUser();
// If logged in, do some stuff
if (csfd.userUrl !== undefined) {
// If movie ratings not loaded in LocalStorage...
csfd.REFRESH_RATINGS();
}
// --> THIS IS CALLED BEFORE REFRESH_RATINGS ENDS IF I DO async: true
if (Object.keys(this.stars).length != 0) {
// Continue after movie ratings are loaded
csfd.addRatingsColumn();
}
}
解决方案
您可以将 ajax 调用包装Promise
在调用返回时解析的 a 中。像这样的东西:
(async () => {
...
async REFRESH_RATINGS() {
// Load user ratings...
return new Promise((resolve, reject) => {
$.ajax({
type: "GET",
url: this.userRatingsUrl, // page when pagination of all ratings starts
async: true
}).done((data) => {
this.processRatingsPage(data);
resolve();
})
});
}
...
if (csfd.userUrl !== undefined) {
// If movie ratings not loaded in LocalStorage...
await csfd.REFRESH_RATINGS();
}
...
推荐阅读
- html - 想要将 div 与 ion-label 居中,但后者的宽度为 100%
- android - 片段销毁时服务内的 mediaPlayer 停止
- angular - “MouseEvent未定义”客户端在primeng angular 4中不起作用?
- csv - 在 Solr 管理员中上传 CSV 文件时出现问题
- kubernetes - 法兰绒版本兼容性
- python - 将列表的每个元素与另一个列表中的相应索引进行比较
- xamarin - 如何从数据表中显示列表视图?
- sql-server - 如何一般地创建分层xml
- c# - 为什么重新加载后datagridview的列大小不同
- apache-spark - Spark 流式处理在每小时 00:00 运行