美文网首页
JS新Web API:EventTarget.when(下)

JS新Web API:EventTarget.when(下)

作者: 塞风 | 来源:发表于2025-08-31 14:04 被阅读0次

1.用法:const observer = eventTarget.when(eventType);

  • eventTarget: 任何继承自 EventTarget 的对象,如 HTMLElement、Window、XMLHttpRequest、Web Socket 等。
  • eventType: 字符串,表示要监听的事件类型(如 'click'、'load'、'input')
  • observer: Observer实例对象,包含方法如图:


    observer实例

2.实例方法

  • reducereduce方法的调用需结合take(n)方法使用,事件触发n次后,返回结果打印日志,之后事件不会再调用了
const ob = document.body.when('click');
const r = await ob.take(3).reduce(function (total, delta, t) {
  console.log('total: ', total);
  console.log('点击次数:', t);
  return {
      totalDx: total.totalDx + delta.clientX,
      totalDy: total.totalDy + delta.clientY
  }
}, { totalDx: 0, totalDy: 0 })
console.log('触发三次后结果', r);
image.png
  • toArraytoArray方法的调用结合take(n)方法使用,事件触发n次后,收集n次事件后的结果并返回,之后事件不会再调用了
async function handleClick() {
  const ob = document.when('click');
  const r = await ob.take(3).map((event, t) => {
    console.log('点击次数:', t);
      return { x: event.clientX, y: event.clientY }
    }).toArray()
    console.log(r);
  }
  handleClick()
image.png
  • forEachforEach方法的调用结合take(n)方法使用,事件触发n次后不再触发,forEach是否有返回结果看其是否调用then方法返回结果,forEach的回调方法没有返回值
 async function handleClick() {
   let times = 0
   const el = document.getElementById('list');
   const r = await el.when('click')
     .filter((event) => event.target.tagName === 'LI')
     .take(4)
     .forEach((event, t) => {
        console.log('点击次数:', t, event.target.textContent);
        // 这里可以执行副作用操作,如修改UI
        event.target.style.backgroundColor = 'lightblue';
        // 2秒后恢复颜色
       setTimeout(() => {
          event.target.style.backgroundColor = '';
        }, 2000);
        times = t + 1
          return t // 无效返回,为了演示保留
      }).then(res => {
        console.log(res, '--res');
        return times
      })
    console.log('总共点击次数:', r); 
  }
  handleClick()
image.png image.png
  • switchMap: 在switchMap方法里可获取异步数据并返回,在subscribe回调中订阅到返回值,如下图:
 function handleInput() {
  const ob = input.when('input');
  ob.switchMap(event => {
  const val = event.target.value;
  console.log('val: ', val);
  return fetch(`https://jsonplaceholder2.typicode.com/posts/${val}`)
    .then(response => {
      if (response.status !== 200) {
      // throw new Error('请求失败') // subscribe的error回调捕捉
      // return Promise.reject(('请求失败')) // subscribe的error回调捕捉
      return Promise.resolve({ code: 404, data: null, msg: '请求失败' }) //subscribe的next回调捕捉
    }
    return response.json()
    })
  })
  .catch(err => {
    console.log('err1: ', err);
    return { fallback: 'error data' }
    })
    .finally((s) => {
      console.log(s, 'finally');
    })
    .subscribe({
      next(value) {
        console.log('订阅结果是', value);
      },
      error(err) {
        console.log('err2: ', err);
      },
   });
 }
 handleInput()
image.png
这里可结合catchfinally方法使用,注意顺序,catchfinally需在subscribe前调用。当接口返回Promise.reject值或抛出异常时,会被catchfinally方法依次捕捉,同时subscribeerror回调也会触发,若error回调省略则控制台会报错,如下图:
image.png

switchMap的适用场景如搜索框输入提示、表单提交按钮的防重复点击、标签页切换加载数据,比如在input中快速输入值,只有最后一次输入会得到响应结果,前面的输入会发起请求不会得到响应结果,如下图:

function handleInput() {
  const ob = input.when('input');
  ob.flatMap(event => {
    const val = event.target.value;
    console.log('val: ', val);
    return fetch(`https://jsonplaceholder.typicode.com/posts/${val}`)
      .then(response => response.json())
    })
    .subscribe({
      next(value) {
      console.log('订阅结果是', value);
    },
    error(err) {
      console.log('err: ', err);
      },
    });
  }
  handleInput()
image.png
image.png
  • flatMap: 和switchMap类似,适用场景通知、日志记录、需要处理所有请求结果。switchMap是“喜新厌旧” ,新任务一来,立刻放弃旧任务,只处理最新的。flatMap是来一个任务就处理一个,所有任务立即执行,先发先出,但不保证按顺序返回结果
function handleInput() {
  const ob = input.when('input');
  ob.switchMap(event => {
    const val = event.target.value;
    console.log('val: ', val);
    return fetch(`https://jsonplaceholder.typicode.com/posts/${val}`)
      .then(response => response.json())
    })
    .subscribe({
      next(value) {
      console.log('订阅结果是', value);
    },
    error(err) {
      console.log('err: ', err);
      },
    });
  }
  handleInput()
image.png
image.png
  • inspect: inspect方法在开发调试、性能监控和系统维护方面有着独特的价值,他像给数据流安装了一个透明的观察窗口,能够看到数据在每个阶段的形态,而不会影响数据的流动。这在复杂的异步处理流程中特别有价值
function handleInput() {
  const ob = input.when('input');
  ob.map(event => event.target.value)
  .inspect(rawValue => console.log('原始输入:', rawValue))
  .filter(value => value.length > 1)
  .inspect(filteredValue => console.log('过滤后输入:', filteredValue))
  .switchMap(searchTerm => fetch(`https://jsonplaceholder.typicode.com/posts/${searchTerm}`))
  .inspect(response => console.log('API响应:', response.status))
  .switchMap(response => response.json())
  .inspect(data => {
    console.log('解析后的数据:', data);
   })
   .subscribe(results => {
    console.log('最终结果:', results);
   });
  }
 handleInput()
image.png

相关文章

网友评论

      本文标题:JS新Web API:EventTarget.when(下)

      本文链接:https://www.haomeiwen.com/subject/eqtmajtx.html