Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/qt/7.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 返回do while循环异步承诺的最佳实践_Javascript - Fatal编程技术网

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)
        }
    })
}