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作为参数:

与参数一起传递的函数解析和拒绝。这 执行器函数由承诺立即执行 实现,传递解析和拒绝函数(执行程序是 在 Promise 构造函数甚至返回创建的之前调用 对象)。

所以它应该只是对函数的引用,请注意,当你使用 checkDimensions() 调用它时,JS 会立即执行该函数。

因此,您将需要用函数引用包装它,但问题是函数的上下文已更改,并且新上下文中不再存在checkDimensions()

为了保持维度变量上下文,您可以使用以下命令从img.onload内部调用checkDimensions函数:

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.

我建议传递值以解析并在完成时接收。

checkDimensions: function(dimensions) {
console.log('entering chekDimensions');
if (options.maxDimensionsWH > 0) {
console.log(dimensions.width);
console.log(dimensions.height);
if ((dimensions.width <= options.maxDimensionsWH || dimensions.height <= options.maxDimensionsWH)
&& (dimensions.width > 0 && dimensions.height > 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(
{
width:img.width,
height:img.height
});
};
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(function(dimensions) 
{ 
check = this.checkDimensions(dimensions) 
});

最新更新