jquery .done() 仍然在 deferred.resolve() 之前运行
jquery .done() still runs before 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
:
作为参数
A function that is passed with the arguments resolve and reject. The
executor function is executed immediately by the Promise
implementation, passing resolve and reject functions (the executor is
called before the Promise constructor even returns the created
object).
所以它应该只是一个 reference 函数,注意当你用 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)
});
我已经在这里阅读了几个关于这个主题的问题,但我仍然看不出有什么问题。我有两个函数,一个从文件初始化图像并读取它的尺寸,将它们设置为对象的变量。第二个检查尺寸是否在限制范围内。
函数:
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
:
A function that is passed with the arguments resolve and reject. The executor function is executed immediately by the Promise implementation, passing resolve and reject functions (the executor is called before the Promise constructor even returns the created object).
所以它应该只是一个 reference 函数,注意当你用 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)
});