uni-app 最近几个版本 ctx.measureText 无法在 for 循环中正确获取第一个 text width 的问题

uni-app 最近几个版本 ctx.measureText 无法在 for 循环中正确获取第一个 text width 的问题

信息类别 详细信息
产品分类 uniapp/App
PC开发环境操作系统 Mac
PC开发环境操作系统版本号 11.4
HBuilderX类型 Alpha
HBuilderX版本号 3.1.22
手机系统 Android
手机系统版本号 Android 10
手机厂商 模拟器
手机机型 Pixel XL API 29
页面类型 vue
打包方式 云端
项目创建方式 HBuilderX

操作步骤:

请看描述

预期结果:

准确拿到 text 的 width

实际结果:

无法拿到第一个 text 的width

bug描述:

ctx.measureText 在 for 循环中,第一个 text 的 width 始终是 null,该问题在安卓端可复现
运行附件中的demo,注意查看 console

Image 1
Image 2

almost-lottery_sample.zip


更多关于uni-app 最近几个版本 ctx.measureText 无法在 for 循环中正确获取第一个 text width 的问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html

5 回复

其他设备是否正常?

更多关于uni-app 最近几个版本 ctx.measureText 无法在 for 循环中正确获取第一个 text width 的问题的实战教程也可以访问 https://www.itying.com/category-93-b0.html


应该是极少部分手机,身边多台安卓,redmi9可复现,图片中的2个模拟器是必现的

刚才对模拟器频繁测试,偶尔又会正常

先不管,暂时解决了

这是一个已知的异步执行时序问题。在 for 循环中,ctx.measureText 的异步回调函数执行顺序不确定,导致第一个文本的测量结果可能最后返回或被覆盖。

建议改用以下方案:

  1. 使用 Promise 包装测量逻辑
const measureText = (ctx, text) => {
  return new Promise(resolve => {
    ctx.measureText(text, res => {
      resolve(res.width)
    })
  })
}
  1. 使用 async/await 顺序执行
async function measureAllTexts() {
  const texts = ['文本1', '文本2', '文本3']
  for (let text of texts) {
    const width = await measureText(ctx, text)
    console.log(`${text} width:`, width)
  }
}
  1. 通过数组索引关联结果
const results = []
texts.forEach((text, index) => {
  ctx.measureText(text, res => {
    results[index] = res.width
    // 检查是否所有测量完成
    if(results.filter(v => v !== undefined).length === texts.length) {
      console.log('所有测量完成:', results)
    }
  })
})
回到顶部