gpt4 book ai didi

javascript - JQuery 和 XHR 请求异步问题

转载 作者:行者123 更新时间:2023-11-28 00:53:19 25 4
gpt4 key购买 nike

我正在尝试为使用 Google Chrome 扩展程序找到音乐 url 的每个 div 应用生成的音频图图像。

但是,从 url 下载音乐和处理图像的过程需要足够的时间,以至于所有图像都会一直应用到最后一个 div。

我正在尝试将图像应用于每个 div,就像贯穿 JQuery 的每个请求一样。所有的 div 都在播放 /renderload.gif gif,但只有最后一个 div 会随着图像一张一张地完成处理而闪烁。

例如,所有 1,2,3,4,5 的 src 都设置为 /renderload.gif

但是一旦下载了声音 blob 并生成了图像,只有 4-5 获取图像并且它继续加载队列,重复这个问题。

这是我正在尝试处理的示例。 enter image description here

这是我最近尝试通过一次加载所有音频来添加队列以避免延迟,但问题似乎仍然存在。

// context.js
function Queue(){
var queue = [];
var offset = 0;
this.getLength = function(){
return (queue.length - offset);
}
this.isEmpty = function(){
return (queue.length == 0);
}
this.setEmpty = function(){
queue = [];
return true;
}
this.enqueue = function(item){
queue.push(item);
}
this.dequeue = function(){
if (queue.length == 0) return undefined;
var item = queue[offset];
if (++ offset * 2 >= queue.length){
queue = queue.slice(offset);
offset = 0;
}
return item;
}
this.peek = function(){
return (queue.length > 0 ? queue[offset] : undefined);
}
}


var audioqueue=new Queue();
var init=0;
var current=0;
var finished=0;


function RunGraphs(x) {
if (x==init) {
if (audioqueue.isEmpty()==false) {
current++;
var das=audioqueue.dequeue();
var divparent=das.find(".original-image");
var songurl=das.find(".Mpcs").find('span').attr("data-url");
console.log("is song url "+songurl);
console.log("is data here "+divparent.attr("title"));
divparent.css('width','110px');
divparent.attr('src','https://i.pinimg.com/originals/a4/f2/cb/a4f2cb80ff2ae2772e80bf30e9d78d4c.gif');
var blob = null;
var xhr = new XMLHttpRequest();
xhr.open("GET",songurl,true);
xhr.responseType = "blob";//force the HTTP response, response-type header to be blob
xhr.onload = function() {
blob = xhr.response;//xhr.response is now a blob object
console.log(blob);
SCWFRobloxAudioTool.generate(blob, {
canvas_width: 110,
canvas_height: 110,
bar_width: 1,
bar_gap : .2,
wave_color: "#ecb440",
download: false,
onComplete: function(png, pixels) {
if (init == x) {
divparent.attr('src',png);
finished++;
}
}
});
}
xhr.send();
OnHold(x);
}
}
}
function OnHold(x) {
if (x==init) {
if (current > finished+7) {
setTimeout(function(){
OnHold(x)
},150)
} else {
RunGraphs(x)
}
}
}
if (window.location.href.includes("/lib?Ct=DevOnly")){
functionlist=[];
current=0;
finished=0;
init++;
audioqueue.setEmpty();
$(".CATinner").each(function(index) {
(function(x){
audioqueue.enqueue(x);
}($(this)));
});
RunGraphs(init);
};

SCWFAudioTool 来自这个 github 存储库。 Soundcloud Waveform Generator

来自搜索请求的 Queue.js,稍作修改以支持 setEmpty。 Queue.js

最佳答案

请阅读帖子的编辑部分

为了检查您的 Queue 和 defer 方法,我为您的代码制作了一个可用的最小示例。似乎没有我能找到的错误(我没有 html 文件,无法检查丢失的文件。请通过将 if (this.status >= 200 && this.status < 400) 检查添加到 onload 回调来自己执行此操作):

// context.js
function Queue(){
var queue = [];
var offset = 0;
this.getLength = function(){
return (queue.length - offset);
}
this.isEmpty = function(){
return (queue.length == 0);
}
this.setEmpty = function(){
queue = [];
return true;
}
this.enqueue = function(item){
queue.push(item);
}
this.dequeue = function(){
if (queue.length == 0) return undefined;
var item = queue[offset];
if (++ offset * 2 >= queue.length){
queue = queue.slice(offset);
offset = 0;
}
return item;
}
this.peek = function(){
return (queue.length > 0 ? queue[offset] : undefined);
}
}


var audioqueue=new Queue();
var init=0;
var current=0;
var finished=0;


function RunGraphs(x) {
if (x==init) {
if (audioqueue.isEmpty()==false) {
current++;
var songurl = audioqueue.dequeue();

console.log("is song url "+songurl);
var blob = null;
var xhr = new XMLHttpRequest();
xhr.open("GET",songurl,true);
xhr.responseType = "blob";//force the HTTP response, response-type header to be blob
xhr.onload = function() {

if (this.status >= 200 && this.status < 400) {
blob = xhr.response;//xhr.response is now a blob object
console.log('OK');
finished++;
} else {
console.log('FAIL');
}
}
xhr.send();
OnHold(x);
}
}
}
function OnHold(x) {
if (x==init) {
if (current > finished+7) {
setTimeout(function(){
OnHold(x)
},150)
} else {
RunGraphs(x)
}
}
}

var demoObject = new Blob(["0".repeat(1024*1024*2)]); // 2MB Blob
var demoObjectURL = URL.createObjectURL(demoObject);
if (true){
functionlist=[];
current=0;
finished=0;
init++;
audioqueue.setEmpty();
for(var i = 0; i < 20; i++)
audioqueue.enqueue(demoObjectURL);
RunGraphs(init);
};

因此,如果没有关于丢失文件的错误,我能想到的唯一错误与 SCWFRobloxAudioTool.generate 有关。方法。

请检查回调是否被正确触发,并且在转换过程中没有产生错误。

如果您提供额外的附加信息、数据或代码,我可以调查这个问题。

编辑:

我查看了“SoundCloudWaveform”程序,我想我看到了问题:

该模块不是一次处理多个查询(只有一个全局设置对象。因此每次尝试向 api 添加另一个查询都会覆盖前一个的回调,并且由于 fileReader 是异步调用只会执行最新添加的回调。)

请考虑使用此 api 的 oop 尝试:

window.AudioContext = window.AudioContext || window.webkitAudioContext;

Array.prototype.max = function() {
return Math.max.apply(null, this);
};

function SoundCloudWaveform (){

this.settings = {
canvas_width: 453,
canvas_height: 66,
bar_width: 3,
bar_gap : 0.2,
wave_color: "#666",
download: false,
onComplete: function(png, pixels) {}
}

this.generate = function(file, options) {

// preparing canvas
this.settings.canvas = document.createElement('canvas');
this.settings.context = this.settings.canvas.getContext('2d');

this.settings.canvas.width = (options.canvas_width !== undefined) ? parseInt(options.canvas_width) : this.settings.canvas_width;
this.settings.canvas.height = (options.canvas_height !== undefined) ? parseInt(options.canvas_height) : this.settings.canvas_height;

// setting fill color
this.settings.wave_color = (options.wave_color !== undefined) ? options.wave_color : this.settings.wave_color;

// setting bars width and gap
this.settings.bar_width = (options.bar_width !== undefined) ? parseInt(options.bar_width) : this.settings.bar_width;
this.settings.bar_gap = (options.bar_gap !== undefined) ? parseFloat(options.bar_gap) : this.settings.bar_gap;

this.settings.download = (options.download !== undefined) ? options.download : this.settings.download;

this.settings.onComplete = (options.onComplete !== undefined) ? options.onComplete : this.settings.onComplete;

// read file buffer
var reader = new FileReader();
var _this = this;
reader.onload = function(event) {
var audioContext = new AudioContext()
audioContext.decodeAudioData(event.target.result, function(buffer) {
audioContext.close();
_this.extractBuffer(buffer);
});
};
reader.readAsArrayBuffer(file);
}

this.extractBuffer = function(buffer) {
buffer = buffer.getChannelData(0);
var sections = this.settings.canvas.width;
var len = Math.floor(buffer.length / sections);
var maxHeight = this.settings.canvas.height;
var vals = [];
for (var i = 0; i < sections; i += this.settings.bar_width) {
vals.push(this.bufferMeasure(i * len, len, buffer) * 10000);
}

for (var j = 0; j < sections; j += this.settings.bar_width) {
var scale = maxHeight / vals.max();
var val = this.bufferMeasure(j * len, len, buffer) * 10000;
val *= scale;
val += 1;
this.drawBar(j, val);
}

if (this.settings.download) {
this.generateImage();
}
this.settings.onComplete(this.settings.canvas.toDataURL('image/png'), this.settings.context.getImageData(0, 0, this.settings.canvas.width, this.settings.canvas.height));
// clear canvas for redrawing
this.settings.context.clearRect(0, 0, this.settings.canvas.width, this.settings.canvas.height);
},

this.bufferMeasure = function(position, length, data) {
var sum = 0.0;
for (var i = position; i <= (position + length) - 1; i++) {
sum += Math.pow(data[i], 2);
}
return Math.sqrt(sum / data.length);
},

this.drawBar = function(i, h) {

this.settings.context.fillStyle = this.settings.wave_color;

var w = this.settings.bar_width;
if (this.settings.bar_gap !== 0) {
w *= Math.abs(1 - this.settings.bar_gap);
}
var x = i + (w / 2),
y = this.settings.canvas.height - h;

this.settings.context.fillRect(x, y, w, h);
},

this.generateImage = function() {
var image = this.settings.canvas.toDataURL('image/png');

var link = document.createElement('a');
link.href = image;
link.setAttribute('download', '');
link.click();
}
}

console.log(new SoundCloudWaveform());

也可以考虑简单地为队列使用一个数组:

function Queue(){
var queue = [];
var offset = 0;
this.getLength = function(){
return (queue.length - offset);
}
this.isEmpty = function(){
return (queue.length == 0);
}
this.setEmpty = function(){
queue = [];
return true;
}
this.enqueue = function(item){
queue.push(item);
}
this.dequeue = function(){
if (queue.length == 0) return undefined;
var item = queue[offset];
if (++ offset * 2 >= queue.length){
queue = queue.slice(offset);
offset = 0;
}
return item;
}
this.peek = function(){
return (queue.length > 0 ? queue[offset] : undefined);
}
}

var q = new Queue();
q.enqueue(1)
q.enqueue(2)
q.enqueue(3)
console.log(q.dequeue());
console.log(q.dequeue());
console.log(q.dequeue());
console.log(q.dequeue());


var q2 = [];
q2.push(1)
q2.push(2)
q2.push(3)
console.log(q2.shift());
console.log(q2.shift());
console.log(q2.shift());
console.log(q2.shift());

它可以防止混淆,因为它在您的应用程序中的加速是最小的。

关于javascript - JQuery 和 XHR 请求异步问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46068916/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com