您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
A simple queue for GM_xmlhttpRequests or other async functions
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.cn-greasyfork.org/scripts/370011/610040/RequestQueue.js
- // ==UserScript==
- // @exclude *
- // ==UserLibrary==
- // @name RequestQueue
- // @description A simple queue for GM_xmlhttpRequests or other async functions
- // @version 6
- // @license MIT
- // ==/UserLibrary==
- // @namespace cuzi
- // @homepageURL https://github.com/cvzi/RequestQueue/
- // @grant GM_xmlhttpRequest
- // @grant GM.xmlhttpRequest
- // ==/UserScript==
- // ==OpenUserJS==
- // @author cuzi
- // ==/OpenUserJS==
- "use strict";
- function RequestQueue(maxParallel,maxTotal) {
- // A simple queue for GM_xmlhttpRequests or other async functions
- maxParallel = parseInt(maxParallel)>0?parseInt(maxParallel):1;
- maxTotal = parseInt(maxTotal)>0?parseInt(maxTotal):Number.POSITIVE_INFINITY;
- var index = 0; // incrementing, used for unique ids
- var finished = 0; // Number of finished requests
- var pending = [];
- var running = [];
- var defaultFunction;
- if(typeof GM != "undefined" && "xmlHttpRequest" in GM) {
- defaultFunction = GM.xmlHttpRequest;
- } else {
- defaultFunction = function(a,b,c,d) { return GM_xmlhttpRequest(a,b,c,d);} // Wrap GM_xmlhttpRequest to avoid security exception
- }
- /*
- The internal request Object extended by add(req,fun,thisArg)
- {
- __fun : fun, defaults to GM_xmlhttpRequest
- __thisArg : thisArg, the this object for the above function
- __result : the return value of __fun is saved in this property
- __org_onload : The original event callbacks of req
- __org_onerror
- __org_onabort
- onload : The new event callbacks that wrap the above callbacks
- onerror
- onabort
- ... and all the original properties of the "req" object
- }
- */
- var fire = function() {
- // Check for pending requests and send them.
- if(pending.length > 0 && running.length < maxParallel && finished < maxTotal) {
- var req = pending.shift();
- running.push(req);
- req.__result = req.__fun.call(req.__thisArg,req);
- fire();
- }
- };
- var remove = function(id) {
- // Remove the request with id from the the running array
- for(var i = 0; i < running.length; i++) {
- if(running[i].id == id) {
- running.splice(i, 1);
- finished++;
- fire();
- break;
- }
- }
- };
- this.add = function(req,fun,thisArg) {
- // Schedule a request: add(req[, fun[, thisArg]])
- // fun: defaults to GM.xmlHttpRequest
- // thisArg: The value of this provided for the call to fun. Keep strict mode in mind!
- req.id = index++;
- req.__fun = typeof(fun) === 'function'?fun:defaultFunction;
- req.__thisArg = thisArg;
- // Wrap events that indicate that the request has finished
- req.__org_onload = req.onload;
- req.onload = function(response) {
- if(response.status === 0) { // This is true if a request was aborted. This seems to happen only sporadically
- req.onabort(response);
- return;
- }
- remove(req.id);
- if(req.__org_onload) req.__org_onload(response);
- };
- req.__org_onerror = req.onerror;
- req.onerror = function(response) {
- remove(req.id);
- if(req.__org_onerror) req.__org_onerror(response);
- };
- req.__org_onabort = req.onabort;
- req.onabort = function(response) {
- remove(req.id);
- if(req.__org_onabort) req.__org_onabort(response);
- };
- pending.push(req);
- fire();
- };
- this.abortRunning = function() {
- // For any added function that was already run: result = thisArg.fun(req)
- // it will call result.abort()
- // For GM_xmlhttpRequest this will subsequently fire an onabort event
- for(var i = 0; i < running.length; i++) {
- if(running[i] && typeof running[i].__result.abort === 'function') {
- running[i].__result.abort();
- }
- }
- };
- this.abortPending = function() {
- // Clear the pending list
- pending = [];
- };
- this.abort = function() {
- // Abort both running and pending requests
- this.abortPending();
- this.abortRunning();
- };
- this.resetTotal = function() {
- // Reset number of finished requests
- finished = 0;
- }
- this.hasReachedTotal = function() {
- // Number of maximum allowed requests reached?
- return finished >= maxTotal;
- }
- this.hasRunning = function() {
- // Are there any running requests?
- return running.length > 0;
- }
- }