Tauri:将listen(eventName, handler)转换为Angular可处理的Observable
将类Promise事件转换为Observable的问题
在纯JS环境下官方文档的指导效果良好,但Angular开发场景中我更倾向于使用Observable而非Promise来处理事件。问题在于这个类Promise的事件带有处理函数,我尝试了以下两种方法均未生效:
from(listen("click", v => v))
let x = async() => listen("click", v => v)
每次得到的响应都是如下函数:
function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }
请问如何将这类事件转换为Observable?
解决方案
你调用listen后得到的是返回Promise的函数,而非直接的Promise实例,这是from操作符失效的核心原因。可以通过以下几种方法处理:
方法1:先执行函数获取Promise,再转Observable
先调用listen返回的函数拿到真实的Promise实例,再用from转换:
import { from } from 'rxjs'; // 执行listen返回的函数,得到Promise const clickPromise = listen("click", v => v)(); // 转换为Observable const click$ = from(clickPromise);
方法2:用bindCallback包装(通用方案)
RxJS的bindCallback可以直接把这类返回Promise的函数包装成返回Observable的函数:
import { bindCallback } from 'rxjs'; // 包装listen,得到Observable版本的监听函数 const listenAsObservable = bindCallback(listen); // 调用后直接得到Observable const click$ = listenAsObservable("click", v => v);
方法3:自定义Observable封装
如果上述方法不适用,可以手动创建Observable来封装事件逻辑:
import { Observable } from 'rxjs'; const click$ = new Observable(observer => { // 调用listen获取Promise函数并执行 const promiseFn = listen("click", v => v); promiseFn() .then(value => { observer.next(value); observer.complete(); }) .catch(err => { observer.error(err); }); // 返回清理函数(若listen支持取消事件,可在此添加对应逻辑) return () => { // 事件取消逻辑 }; });
注意:如果listen对应是多次触发的事件(比如点击事件会重复触发),但它返回的Promise只会resolve一次,这种情况下建议改用Angular自带的HostListener或RxJS的fromEvent直接监听DOM事件。
内容的提问来源于stack exchange,提问作者Jean-Paul Abi-Ghosn
相关产品推荐
相关产品推荐

