封装字符串的异步替换方法

334 阅读1分钟

应用场景

将多个 id 通过符号拼接成字符串,需求将字符串中的所有 id 替换成对应的 username

// 如下字符串
const string = '1,2-3_12——13'

// 我们希望结果如下
const result = 'name1,name2-name3_name12——name13'

实现思路

  • 首先我们需要一个能够根据 id 获取对应 username 的方法
function getNameById(id) {
    const name = ...
    return name
}
  • 然后使用字符串的 replace 方法来进行替换即可
const result = string.replace(/\d+/g, (match) => {
   return  getNameById(match)
})

如果 getNameById 方法是同步的,那么到这一步就可以实现了。

但是在很多情况下这个方法是异步的,例如返回一个 Promise 对象,如下

function getNameById(id) {
    return new Promise((resolve) => {
        resolve('name' + id)
    })
}

这时就不能直接使用 replace 方法来进行替换,因为 replace 方法不支持异步的操作。

这时我们就要自己去实现异步的 replace 方法。

实现异步的 replace 方法

// 封装一个替换函数
async function asyncReplace(template) {
    // 获取字符串中的所有数字
    const matchs = template.match(/\d+/g)
    
    // 遍历数组
    for (const item of matchs) {
        // 根据 id 获取到对应的 username
        const res = await getNameById(item)
        // 将字符串对应位置的数字替换成 username
        template = template.replace(item, res)
    }
}

上面这个方案会出现一些问题,因此有了方案二

async function asyncReplace(template) {
    
    // 获取所有数字及非数字
    const matchs = template.match(/\d+|\D+/g)

    let res = matchs.map((i) => {
        return /^\d+$/.test(i) ? getNameById(i) : i
    })
    res = (await Promise.all(res)).join('')
    
    console.log(res);
}

封装成通用函数