1. 本际云推荐 - 专业推荐VPS、服务器,IDC点评首页
  2. 云主机运维
  3. VPS运维

简化until封装watch常用逻辑代码

until方法详解

本文介绍的是Vueuse库中的until方法,它主要是对数据进行监听,在满足一定条件时触发回调。除了常用的toMatch函数外,还包括了适用于特定场景的函数,如watchWithFilter、whenever、watchOnce和watchAtMost等等,一起来看看吧。

简化until封装watch常用逻辑代码

示例

下面是一个使用until方法的示例代码:

<script setup>
  import { until, invoke } from '@vueuse/core'
  import { ref } from 'vue'

  const source = ref(0)

  invoke(async () => {
    await until(source).toBe(4)
    console.log('满足条件了')
  })

  const clickedFn = () => {
    source.value++
  }
</script>

<template>
  <div>{{ source }}</div>
  <button @click="clickedFn">点击按钮</button>
</template>

上面的代码规定了当source的值为4的时候触发执行watch回调函数。而invoke函数则是用于返回函数的执行结果的,这里传入的参数fn是一个函数。当点击按钮累加source的值达到4时,就可以触发watch回调函数,并打印出相应的信息。

源码介绍

下面我们看看until方法的具体源码实现。

toMatch函数

toMatch是判断条件是否满足的基础函数。使用watchAPI来监听数据源r,当满足条件condition时,调用stop停止监听数据源,将promise状态变为成功,并从promises数组中取出该promise。如果用户传了timeout选项,则在promiseTimeout返回的promise实例放入到promises数组中,最后返回Promise.race的结果。

function toMatch(
  condition: (v: any) => boolean,
  { flush = 'sync', deep = false, timeout, throwOnTimeout }: UntilToMatchOptions = {},
): Promise {
  let stop: Function | null = null
  const watcher = new Promise(resolve => {
    stop = watch(
      r,
      (v) => {
        if (condition(v) !== isNot) {
          stop?.()
          resolve(v)
        }
      },
      {
        flush,
        deep,
        immediate: true,
      },
    )
  })

  const promises = [watcher]
  if (timeout != null) {
    promises.push(
      promiseTimeout(timeout, throwOnTimeout)
        .then(() => unref(r))
        .finally(() => stop?.()),
    )
  }
  return Promise.race(promises)
}

toBe函数系列

除了toMatch函数,until方法还封装了适用于特定场景的函数,如以下几个:

  • toBe: 判断是否值相等
  • toBeTruthy: 判断是否为真值
  • toBeNull: 判断是否为null
  • toBeUndefined: 判断是否为undefined
  • toBeNaN: 判断是否为NaN

这几个函数的实现基本上都是调用toMatch函数,并传入相应的参数。比如toBe就是判断是否值相等,如果参数不是引用类型,则直接判断值是否相等,是则返回相应的promise。如果参数是引用类型,则使用watchAPI来监听数据源r和参数value,当两个值相等时,使promise状态变为成功。如下所示:

function toBe

(value: MaybeRef

, options?: UntilToMatchOptions) {
if (!isRef(value))
return toMatch(v => v === value, options)

原创文章,作者:小编小本本,如若转载,请注明出处:https://www.benjiyun.com/yunzhujiyunwei/vps-yunwei/7263.html