gpt4 book ai didi

javascript - 使用事件对象的嵌套 FileReader onload 函数的回调

转载 作者:行者123 更新时间:2023-12-01 03:46:03 31 4
gpt4 key购买 nike

我几乎已经掌握了理论,但仍被细节所困扰。图像大小调整函数,给定 var $data (这是更改后文件输入的事件对象)将返回 var dataurl (这是一个 dataurl jpeg)。

我的问题是让 dataurl 识别它是在嵌套函数内更新的。如下所示,代码将 data:image/jpg;base64 记录到控制台,显示 dataurl 未更新。

研究让我发现这是由于异步调用造成的,这是有道理的。在继续并打印到控制台之前,变量没有及时更改。我还了解到,这是发出回调来更新变量的标准情况。

经过几次尝试,我找不到一个干净的(或有效的)方法来使用回调更新var。在展示我当前的代码后,我将对此进行扩展:

function clProcessImages($data) {

var filesToUpload = $data.target.files;
var file = filesToUpload[0];
var canvas = document.createElement('canvas');
var dataurl = 'data:image/jpg;base64';

var img = document.createElement("img");

var reader = new FileReader();
reader.onload = function(e, callback) {

img.onload = function () {

var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);

var MAX_WIDTH = 800;
var MAX_HEIGHT = 600;
var width = img.width;
var height = img.height;

if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
dataurl = canvas.toDataURL("image/jpeg",0.8);
callback(dataurl);

}
img.src = e.target.result

}
reader.readAsDataURL(file);

console.log(dataurl); // console log mentioned in question
return dataurl;

};

这就是目前的代码,正在弄清楚如何实现回调。我知道在显示的状态下不会调用回调。

我的第一个障碍是我(似乎)以后无法再次调用 reader.onload 函数,因为它似乎是一个专门在加载对象时触发的事件,而不是其他东西随时手动调用。我最好的猜测是创建一个 reader.onload 将触发的新函数,它将包含所有当前的 reader.onload 函数,我可以稍后直接指定,以发出回调,跳过引用onload事件。

看起来像是一个合理的理论,但后来我被 onload 函数传递的 event 对象 困住了。假设我应用上述理论,并且 onload 事件调用新函数 readerOnLoad(e)。它可以很好地通过事件对象。但是,当想要稍后执行回调时,我如何手动调用 readerOnLoad(e) 因为我没有看到从同一对象传递事件对象的方法FileReader 以一种优雅的方式。感觉有点像我误入了非常困惑的代码*来解决,而感觉对于感觉不太利基的情况应该有一些更优雅的东西。

*原始的$data 事件对象变量是通过在文件输入检测到更改时存储全局变量来获得的。理论上,我可以创建一个全局变量来存储 FileReader 加载的事件对象。感觉很复杂,因为我的原始代码和以这种方式运行的代码之间的差异非常严重且不优雅,而唯一的区别是更新未及时准备好的变量。

最佳答案

使用异步函数时,您通常希望将函数作为回调传递。您可以像这样使用 NodeJS 风格的回调:

// asyncTask is an asynchronous function that takes 3 arguments, the last one being a callback

asyncTask(arg1, arg2, function(err, result) {
if (err) return handleError(err);
handleResult(result);
})

所以对于你的情况,你可以这样做:

clProcessImages($data, function(dataurl) {
console.log(dataurl);
// Do you other thing here
});

function clProcessImages($data, onProcessedCallback) {
var filesToUpload = $data.target.files;
var file = filesToUpload[0];
var canvas = document.createElement('canvas');
var dataurl = 'data:image/jpg;base64';

var img = document.createElement("img");

var reader = new FileReader();
reader.onload = function(e) {

img.onload = function () {

var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0);

var MAX_WIDTH = 800;
var MAX_HEIGHT = 600;
var width = img.width;
var height = img.height;

if (width > height) {
if (width > MAX_WIDTH) {
height *= MAX_WIDTH / width;
width = MAX_WIDTH;
}
} else {
if (height > MAX_HEIGHT) {
width *= MAX_HEIGHT / height;
height = MAX_HEIGHT;
}
}
canvas.width = width;
canvas.height = height;
var ctx = canvas.getContext("2d");
ctx.drawImage(img, 0, 0, width, height);
dataurl = canvas.toDataURL("image/jpeg",0.8);
onProcessedCallback(dataurl);

}
img.src = e.target.result

}
reader.readAsDataURL(file);

return dataurl;
};

您可能还想像第一个示例一样将 error 对象传递给回调,并适本地处理它。

简而言之,始终将回调函数作为参数添加到您自己的异步函数中。

关于javascript - 使用事件对象的嵌套 FileReader onload 函数的回调,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43569789/

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