Javascript 返回do while循环异步承诺的最佳实践
返回此功能承诺的最佳实践是什么:Javascript 返回do while循环异步承诺的最佳实践,javascript,Javascript,返回此功能承诺的最佳实践是什么: function calculateTextSize(guide){ do { default_size -= 0.1; text_Height = getTextHeight(guide, `bold ${default_size}vw Open Sans`) + 10; } while (text_Height > height); do {
function calculateTextSize(guide){
do {
default_size -= 0.1;
text_Height = getTextHeight(guide, `bold ${default_size}vw Open Sans`) + 10;
}
while (text_Height > height);
do {
default_size -= 0.1;
text_Length = getTextWidth(guide, `bold ${default_size}vw Open Sans`).toFixed(2);
}
while (text_Length > width);
};
function getTextWidth(text, font) {
var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
var context = canvas.getContext("2d");
context.font = font;
var metrics = context.measureText(text);
return metrics.width;
};
//Start Of Text Height Function
function getTextHeight(text, font) {
let canvas = document.createElement("canvas")
let context = canvas.getContext("2d");
let sourceWidth = canvas.width;
let sourceHeight = canvas.height;
context.font = font;
// place the text somewhere
context.textAlign = "left";
context.textBaseline = "top";
context.fillText(text, 25, 5);
// returns an array containing the sum of all pixels in a canvas
// * 4 (red, green, blue, alpha)
// [pixel1Red, pixel1Green, pixel1Blue, pixel1Alpha, pixel2Red ...]
let data = context.getImageData(0, 0, sourceWidth, sourceHeight).data;
let firstY = -1;
let lastY = -1;
// loop through each row
for(let y = 0; y < sourceHeight; y++) {
// loop through each column
for(let x = 0; x < sourceWidth; x++) {
//var red = data[((sourceWidth * y) + x) * 4];
//var green = data[((sourceWidth * y) + x) * 4 + 1];
//var blue = data[((sourceWidth * y) + x) * 4 + 2];
let alpha = data[((sourceWidth * y) + x) * 4 + 3];
if(alpha > 0) {
firstY = y;
// exit the loop
break;
}
}
if(firstY >= 0) {
// exit the loop
break;
}
}
// loop through each row, this time beginning from the last row
for(let y = sourceHeight; y > 0; y--) {
// loop through each column
for(let x = 0; x < sourceWidth; x++) {
var alpha = data[((sourceWidth * y) + x) * 4 + 3];
if(alpha > 0) {
lastY = y;
// exit the loop
break;
}
}
if(lastY >= 0) {
// exit the loop
break;
}
}
return lastY - firstY;
};
我想在异步函数中等待calculateTextSize,如:
async function foo(){
await calculateTextSize();
//After calculateTextSize has finished its work do stuff..
}
我已经试过了,但我不确定这是否是最好的或至少是好的做法:如果Javascript编译器先等待do while循环完成,然后转到下一行,这可能是好的做法,但我不知道JS编译器如何处理do while循环
function calculateTextSize(guide){
do {
default_size -= 0.1;
text_Height = getTextHeight(guide, `bold ${default_size}vw Open Sans`) + 10;
}
while (text_Height > height);
do {
default_size -= 0.1;
text_Length = getTextWidth(guide, `bold ${default_size}vw Open Sans`).toFixed(2);
}
while (text_Length > width);
return new Promise((resolve) => {
resolve();
});
};
更新:下面是getTextWidth函数:
function calculateTextSize(guide){
do {
default_size -= 0.1;
text_Height = getTextHeight(guide, `bold ${default_size}vw Open Sans`) + 10;
}
while (text_Height > height);
do {
default_size -= 0.1;
text_Length = getTextWidth(guide, `bold ${default_size}vw Open Sans`).toFixed(2);
}
while (text_Length > width);
};
function getTextWidth(text, font) {
var canvas = getTextWidth.canvas || (getTextWidth.canvas = document.createElement("canvas"));
var context = canvas.getContext("2d");
context.font = font;
var metrics = context.measureText(text);
return metrics.width;
};
//Start Of Text Height Function
function getTextHeight(text, font) {
let canvas = document.createElement("canvas")
let context = canvas.getContext("2d");
let sourceWidth = canvas.width;
let sourceHeight = canvas.height;
context.font = font;
// place the text somewhere
context.textAlign = "left";
context.textBaseline = "top";
context.fillText(text, 25, 5);
// returns an array containing the sum of all pixels in a canvas
// * 4 (red, green, blue, alpha)
// [pixel1Red, pixel1Green, pixel1Blue, pixel1Alpha, pixel2Red ...]
let data = context.getImageData(0, 0, sourceWidth, sourceHeight).data;
let firstY = -1;
let lastY = -1;
// loop through each row
for(let y = 0; y < sourceHeight; y++) {
// loop through each column
for(let x = 0; x < sourceWidth; x++) {
//var red = data[((sourceWidth * y) + x) * 4];
//var green = data[((sourceWidth * y) + x) * 4 + 1];
//var blue = data[((sourceWidth * y) + x) * 4 + 2];
let alpha = data[((sourceWidth * y) + x) * 4 + 3];
if(alpha > 0) {
firstY = y;
// exit the loop
break;
}
}
if(firstY >= 0) {
// exit the loop
break;
}
}
// loop through each row, this time beginning from the last row
for(let y = sourceHeight; y > 0; y--) {
// loop through each column
for(let x = 0; x < sourceWidth; x++) {
var alpha = data[((sourceWidth * y) + x) * 4 + 3];
if(alpha > 0) {
lastY = y;
// exit the loop
break;
}
}
if(lastY >= 0) {
// exit the loop
break;
}
}
return lastY - firstY;
};
将函数代码包装在promise对象中,并根据数据进行解析或拒绝
function calculateTextSize(guide) {
return new Promise((resolve, reject) => {
do {
default_size -= 0.1;
text_Height = getTextHeight(guide, `bold ${default_size}vw Open Sans`) + 10;
}
while (text_Height > height);
do {
default_size -= 0.1;
text_Length = getTextWidth(guide, `bold ${default_size}vw Open Sans`).toFixed(2);
}
while (text_Length > width);
resolve(`< return data >`);
});
};
或者使用async Wait调用函数
(async function () {
try {
let data = await calculateTextSize();
console.log(data);
} catch(error) {
console.log(error);
}
})()
如果您的函数不执行任何异步任务,那么最好避免承诺。 无论如何,如果要在循环后返回承诺,则应将其更改为以下内容:
function calculateTextSize(guide){
return new Promise((resolve) => {
do {
default_size -= 0.1;
text_Height = getTextHeight(guide, `bold ${default_size}vw Open Sans`) + 10;
}
while (text_Height > height);
do {
default_size -= 0.1;
text_Length = getTextWidth(guide, `bold ${default_size}vw Open Sans`).toFixed(2);
}
while (text_Length > width);
resolve();
});
};
由于我们在循环之后进行解析,这将确保您的计算在解析之前完成。CalculateExtSize函数不会返回承诺。它只是一个函数,在while循环中同步执行某些操作,假设getTextHeight是同步的。为什么要使用wait?函数有可能失败吗?但是您在calculateTextSize中执行异步任务吗?如果不是,那么就没有理由返回承诺。如果getTextWidth做了我认为它做的事情,呈现文本,然后测量它,它是一个同步的,所以承诺对你没有任何帮助,2是你的函数如此缓慢的原因。每次更改DOM后读取DOM时,浏览器都会触发布局并重新绘制,因此测量结果将是准确的。要加快速度,请渲染所有要测量的文本,然后进行所有测量。它仍然是同步的,承诺仍然是无用的,但所需的时间要少得多。编辑:没关系,我知道你在做什么,你需要循环。然后至少进行一次二进制搜索……总之,没有办法对DOM异步进行更改,因为布局是在主线程上执行的。WebWorkers可以并行计算,但不能接触DOM;显然,等待外部工作完成是异步的。在您的情况下,异步或承诺无法为您做任何事情。
If I understand well then you need perform the followings;-
/* await look for a promise , so I will create calculateTextSize() function which return promise.*/
async function foo(){
await calculateTextSize();
//After calculateTextSize has finished its work do stuff..
}
return new Promise(async (resolve,reject) => {
try{
do {
default_size -= 0.1;
text_Height = await getTextHeight(guide, `bold ${default_size}vw Open Sans`);
text_Height = text_Height + 10
}
while (text_Height > height);
do {
default_size -= 0.1;
text_Length = await getTextWidth(guide, `bold ${default_size}vw Open Sans`);
text_Length = text_Length.toFixed(2)
}
while (text_Length > width);
resolve();
});
}catch(error){
reject(error)
}
};
// getTextHeight is also look like a function which need to return promise so
getTextHeight(guide,someStr){
return Promise (async (resolve,reject) => {
try{
//do your stuff
resolve()
}catch(error){
reject(error)
}
})
}