【问题标题】:Binding an async function with decorators using babel使用 babel 将异步函数与装饰器绑定
【发布时间】:2015-04-30 13:18:42
【问题描述】:

我正在尝试在 React 类中绑定一个异步函数。以前我一直在使用 co 这样做

import React from 'react';
import { bind } from 'lodash';
import { wrap } from 'co';
import ajax from 'qajax';

export default class Foo extends React.Component {
    constructor(props) {
        super(props);

        this.handleSubmit = bind(wrap(this.handleSubmit), this);
    }

    *handleSubmit(event) {
        event.preventDefault();

        const Data = { foo: this.state.foo };

        const Result = yield ajax({ /* ... */ data: Data })

        //...
    }
}

效果很好。

我正在尝试重构它以使用 babel 提供的装饰器和异步函数来使代码更干净,就像这样

import React from 'react';
import { bind } from 'lodash';
import { wrap } from 'co';
import ajax from 'qajax';

function AutoBind(target, name, descriptor) {
    let fn = descriptor.value;

    delete descriptor.value;
    delete descriptor.writable;

    descriptor.get = function() {
        return function () { fn.apply(this, arguments); }
    }
}

export default class Foo extends React.Component {
    constructor(props) {
        super(props);
    }

    @AutoBind
    async handleSubmit(event) {
        event.preventDefault();

        const Data = { foo: this.state.foo };

        const Result = await ajax({ /* ... */ data: Data })

        //...
    }
}

后者的问题在于,handleSubmit 函数中的 this 引用被设置为 Window 对象,这可能是由于编译后的输出绑定了 _asyncToGenerator 函数而不是提供的生成器回调函数。编译输出sn -p如下

_createDecoratedClass(Foo, [{
        key: 'handleSubmit',
        decorators: [AutoBind],
        value: _asyncToGenerator(function* (event) {
            event.preventDefault();

            //...
        })
    }

我知道这是一个相当新的领域,这样的问题是可以预料的,我只是想知道是否有人尝试过类似的方法并找到了解决方案,目前我将坚持以前的工作方法。

最后,AutoBind 装饰器在非异步函数上按预期工作,像这样

@AutoBind
handleScreennameChange({ target: { value }}) {
    this.setState({
        screen_name: value
    });
}

【问题讨论】:

  • 等等,你为什么不把那个吸气剂做成function(){ return fn; }?你为什么要使用吸气剂?
  • 我从babeljs.io/blog/2015/03/31/5.0.0 改编了这个例子——虽然我可能不需要

标签: javascript async-await babeljs


【解决方案1】:

所以事实证明这只是我的自动绑定装饰器没有按预期工作。

我使用https://github.com/andreypopp/autobind-decorator 解决了这个问题,而不是滚动我自己的自动绑定

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-29
    • 1970-01-01
    • 1970-01-01
    • 2011-10-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多