装饰器 如何 装饰异步方法

发布于 2022-09-11 21:01:39 字数 849 浏览 17 评论 0

网上一波Decorator 的介绍,给类的方法增加装饰器的都是

let log = (type) => {

  return (target, name, descriptor) => {
    const method = descriptor.value;
    descriptor.value =  (...args) => {
      console.info(`(${type}) 正在执行: ${name}(${args}) = ?`);
      let ret;
      try {
        ret = method.apply(target, args);
        console.info(`(${type}) 成功 : ${name}(${args}) => ${ret}`);
      } catch (error) {
        console.error(`(${type}) 失败: ${name}(${args}) => ${error}`);
      }
      return ret;
    }
  }
}

class Super{

 @log('some_log')
 fetchData(){
 ...
 }

}

这么个操作。

但是如果被装饰fn 是一个promise、异步方法的话,如何做到

// 想在这里来一波log,上面的方法是可以做到的
fetch('http://xxx.xxx.com')
.then((res)=>{
// 想在这里来一波log ,怎么搞?
})

目前我的操作是 fn.toString() 插入一些代码, eval() 成一个方法。
有一些优雅的方法来做这件事么?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

相守太难 2022-09-18 21:01:39

建议用 中间件
promise return 后处理顺序在原代码执行顺序后面,类似这种

function asyncDecorator(name: string) {
  return function(target: Object, _: string, descriptor: PropertyDescriptor) {
    const raw = descriptor.value;

 
    descriptor.value = function(...args: any) {
      return raw.apply(this, args).then(() => {
        console.log('exec log: ', name);
      });
    };
  };
}

class Person {
  @asyncDecorator('test')
  fetch() {
    return new Promise((resolve, reject) => {
      setTimeout(resolve, 300);
    }).then(() => {
      console.log('fetch');
    });
  }
}

const person = new Person();

person.fetch();

可以参考 axios

╰◇生如夏花灿烂 2022-09-18 21:01:39

本质都是js,举一反三一下就行了啊

let log = (type) => {

  return (target, name, descriptor) => {
    const method = descriptor.value;
    descriptor.value =  (...args) => {
      console.info(`(${type}) 正在执行: ${name}(${args}) = ?`);
      let ret;
      try {
        ret = method.apply(target, args);
        ret.then(result=>console.info(`(${type}) 成功 : ${name}(${args}) => ${result}`))
            .catch(error=>console.error(`(${type}) 失败: ${name}(${args}) => ${error}`))
      } catch (error) {
        console.error(`(${type}) 失败: ${name}(${args}) => ${error}`);
      }
      return ret;
    }
  }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文