jquery - jquery .done() 仍然在 deferred.resolve() 之前运行
问题描述
我已经阅读了关于这个主题的几个问题,但我仍然看不出有什么问题。我有两个函数,一个从文件初始化图像并读取其尺寸,将它们设置为对象的变量。第二个检查尺寸是否在限制范围内。
功能:
checkDimensions: function() {
console.log('entering chekDimensions');
if (options.maxDimensionsWH > 0) {
console.log(this.checkWidth);
console.log(this.checkHeight);
if ((this.checkWidth <= options.maxDimensionsWH || this.checkHeight <= options.maxDimensionsWH)
&& (this.checkWidth > 0 && this.checkHeight > 0)) {
console.log('returning true');
return true;
} else {
console.log('returning false');
return false;
}
} else {
return true;
}
},
initializeCheckImage: function(file) {
console.log('entering initialization');
var d = $.Deferred();
var reader = new FileReader();
reader.onload = function (e) {
var img = new Image;
img.onload = function() {
this.checkWidth = img.width;
this.checkHeight = img.height;
console.log('initializing the image');
console.log(this.checkWidth);
console.log(this.checkHeight);
d.resolve();
};
console.log('assigning reader.result');
img.src = reader.result;
};
console.log('assigning a file to the reader');
reader.readAsDataURL(file);
console.log('returning deferred');
return d.promise();
}
以及它们的名称:
this.initializeCheckImage(file).done(check = this.checkDimensions());
从控制台可以清楚地看到,第二个函数的执行发生在d.resolve();
调用之前。
> 21:13:34.460 entering initialization
> 21:13:34.461 assigning a file to the reader
> 21:13:34.462 returning deferred
> 21:13:34.462 entering chekDimensions
> 21:13:34.462 0
> 21:13:34.463 0
> 21:13:34.463 chekDimensions returning false
> 21:13:34.478 assigning reader.result
> 21:13:34.493 initializing the image
> 21:13:34.494 30
> 21:13:34.494 30
我究竟做错了什么?谢谢!
解决方案
立即调用 promise 函数:
this.initializeCheckImage(file).done(check = this.checkDimensions());
该done
函数应该接受一个参数executer
:
使用参数 resolve 和 reject 传递的函数。executor 函数由 Promise 实现立即执行,传递 resolve 和 reject 函数(在 Promise 构造函数甚至返回创建的对象之前调用 executor)。
所以它应该只是对函数的引用,注意当你用 checkDimensions() 调用它时,JS 会立即执行函数。
所以你需要用函数引用来包装它,但问题是函数的上下文已经改变,并且checkDimensions()
在新的上下文中不再存在。
为了保持维度变量上下文,您可以checkDimensions
从 with 内部调用该函数img.onload
:
if (checkDimensions(img.width, img.height)) {
return d.resolve();;
}
else {
return d.reject("Wrong dimensions");
}
this.initializeCheckImage(file)
.then(() => console.log("RESOLVED"))
.catch(() => console.log("REJECTED"));
编辑:
为了保持所需对象的上下文,您可以使用绑定,使用 bind()。
var readerOnload = function(e) {
//code
}
reader.onload = readerOnload.bind(this);
或与:
var self = this;
reader.onload = function() {
//you can use self
}
在您的情况下,将不得不再次这样做imgOnload
。
推荐阅读
- javascript - 如何使用反应在两个 css 类视图类型之间切换
- opengl - 相机 glm / OpenGL 即时模式的示例
- c# - 使 C# 源代码生成器报告的诊断错误出现在 Visual Studio 编辑器中
- docker - Docker - 无法在端口 80 上公开
- c# - 如何评估 LINQ 中两个异构集之间的集差异?
- javascript - 如何在电子中使用文件对话框?
- python-3.x - Python asyncio.subprocess():如何查看它是否还在运行
- php - 如何在 WooCommerce 订单中显示产品自定义字段(自定义 SKU)
- mysql - 为什么我不能在 VS 代码中的 SQL 中创建新连接
- excel - Excel:x天前的条件格式