延期承诺词典
A dictionary of deferred promises
我需要用图像构建 PDF。我认为可以提供指向本地存储文件的链接,但是(请纠正我,我会很高兴)事实证明 PDFmake 只能处理 data:URI 编码图像。
所以现在我必须转换图像,但必须先加载它们,否则我将转换为空白。
想法是将 PDF 建筑代码放在
的括号中
$.when.apply(null, imgData).done(function() { });
据我所知,图像可以随机加载,所以为了防止弄乱它们的顺序,我将它们放入字典中,其中每个值的键是来自初始 imgSources 数组的索引。
现在,我是第一次使用Deferred
class 和$.when
,所以请纠正我的错误用法。
function toDataUrl(src) {
var img = new Image(),
deferred = $.Deferred();
img.crossOrigin = 'Anonymous';
img.onload = function() {
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var dataURL;
canvas.height = this.height;
canvas.width = this.width;
ctx.drawImage(this, 0, 0);
dataURL = canvas.toDataURL('image/jpeg');
deferred.resolve(dataURL);
};
img.src = src;
return deferred.promise();
}
function makepdf() {
var pdfContent, a = [], b = [], kontent = [],
list = $("#tabs ul>li a"),
imgSources = ['images/weledu.jpg'],
imgData = {};
$.getJSON(get_url+'types.php?id='+$('#type').val(), function (newsrc) {
imgSources.push('images/lamps/'+newsrc.data['0'].image);
$.each(imgSources, function(index, src) {
imgData.index = toDataUrl(src);
});
});
$.when.apply(null, imgData).done(function() {
// pdf creation
});
};
如果我在传递给 .done()
的回调中放置一个断点,imgData
对象在那里仍然是空白的!我哪里错了?不是应该完成吗?
这里有一些问题。一是您不能将 $.when.apply
用于对象(字典),只能用于数组。另一个是,当您调用 $.when.apply
时,您的 AJAX 调用尚未完成,因此 imgData
中甚至没有任何数据。
发生的事情是,当您将 empty 对象传递给 $.when.apply
时,它将被视为已解决的承诺(就像您调用 $.when()
没有参数),因此立即调用你的 .done()
方法。这一切都发生在 $.getJSON
完成之前。 (参见 $.when
的文档:https://api.jquery.com/jQuery.when/)
还有一点要注意,在 JavaScript 中,对象是 无序的 ,也就是说你不能总是保证每次都以相同的顺序循环它。为了保证顺序,您需要一个数组。
还有一件事要提及,imgData.index = toDataUrl(src);
并不像您想象的那样。这会向您的对象添加一个名为 "index"
的键,它不会使用 index
的 值 。要执行您期望的操作,请使用 imgData[index] = toDataUrl(src);
.
因此,这里的一种解决方案是将 $.when.apply
放在 中 $.getJSON
并将 imgData
更改为数组。
请注意 $.when
将 保持 您传递给它的参数的顺序(或者在本例中是您 "applied" 给它的数组)。在 .done()
回调中,您将以正确的顺序传递参数(dataURL
值)。
function makepdf() {
var pdfContent, a = [], b = [], kontent = [],
list = $("#tabs ul>li a"),
imgSources = ['images/weledu.jpg'],
imgData = [];
$.getJSON(get_url+'types.php?id='+$('#type').val(), function (newsrc) {
imgSources.push('images/lamps/'+newsrc.data['0'].image);
$.each(imgSources, function(index, src) {
imgData.push(toDataUrl(src));
});
// I've always passed `$` as the 1st parameter here,
// not sure if it matters
$.when.apply($, imgData).done(function(img1, img2) {
// pdf creation
// Use `img1`, `img2`, etc. here
// Or loop over `arguments` to get the `dataURL`s
});
});
}
我需要用图像构建 PDF。我认为可以提供指向本地存储文件的链接,但是(请纠正我,我会很高兴)事实证明 PDFmake 只能处理 data:URI 编码图像。
所以现在我必须转换图像,但必须先加载它们,否则我将转换为空白。
想法是将 PDF 建筑代码放在
的括号中
$.when.apply(null, imgData).done(function() { });
据我所知,图像可以随机加载,所以为了防止弄乱它们的顺序,我将它们放入字典中,其中每个值的键是来自初始 imgSources 数组的索引。
现在,我是第一次使用Deferred
class 和$.when
,所以请纠正我的错误用法。
function toDataUrl(src) {
var img = new Image(),
deferred = $.Deferred();
img.crossOrigin = 'Anonymous';
img.onload = function() {
var canvas = document.createElement('CANVAS');
var ctx = canvas.getContext('2d');
var dataURL;
canvas.height = this.height;
canvas.width = this.width;
ctx.drawImage(this, 0, 0);
dataURL = canvas.toDataURL('image/jpeg');
deferred.resolve(dataURL);
};
img.src = src;
return deferred.promise();
}
function makepdf() {
var pdfContent, a = [], b = [], kontent = [],
list = $("#tabs ul>li a"),
imgSources = ['images/weledu.jpg'],
imgData = {};
$.getJSON(get_url+'types.php?id='+$('#type').val(), function (newsrc) {
imgSources.push('images/lamps/'+newsrc.data['0'].image);
$.each(imgSources, function(index, src) {
imgData.index = toDataUrl(src);
});
});
$.when.apply(null, imgData).done(function() {
// pdf creation
});
};
如果我在传递给 .done()
的回调中放置一个断点,imgData
对象在那里仍然是空白的!我哪里错了?不是应该完成吗?
这里有一些问题。一是您不能将 $.when.apply
用于对象(字典),只能用于数组。另一个是,当您调用 $.when.apply
时,您的 AJAX 调用尚未完成,因此 imgData
中甚至没有任何数据。
发生的事情是,当您将 empty 对象传递给 $.when.apply
时,它将被视为已解决的承诺(就像您调用 $.when()
没有参数),因此立即调用你的 .done()
方法。这一切都发生在 $.getJSON
完成之前。 (参见 $.when
的文档:https://api.jquery.com/jQuery.when/)
还有一点要注意,在 JavaScript 中,对象是 无序的 ,也就是说你不能总是保证每次都以相同的顺序循环它。为了保证顺序,您需要一个数组。
还有一件事要提及,imgData.index = toDataUrl(src);
并不像您想象的那样。这会向您的对象添加一个名为 "index"
的键,它不会使用 index
的 值 。要执行您期望的操作,请使用 imgData[index] = toDataUrl(src);
.
因此,这里的一种解决方案是将 $.when.apply
放在 中 $.getJSON
并将 imgData
更改为数组。
请注意 $.when
将 保持 您传递给它的参数的顺序(或者在本例中是您 "applied" 给它的数组)。在 .done()
回调中,您将以正确的顺序传递参数(dataURL
值)。
function makepdf() {
var pdfContent, a = [], b = [], kontent = [],
list = $("#tabs ul>li a"),
imgSources = ['images/weledu.jpg'],
imgData = [];
$.getJSON(get_url+'types.php?id='+$('#type').val(), function (newsrc) {
imgSources.push('images/lamps/'+newsrc.data['0'].image);
$.each(imgSources, function(index, src) {
imgData.push(toDataUrl(src));
});
// I've always passed `$` as the 1st parameter here,
// not sure if it matters
$.when.apply($, imgData).done(function(img1, img2) {
// pdf creation
// Use `img1`, `img2`, etc. here
// Or loop over `arguments` to get the `dataURL`s
});
});
}