【问题标题】:Error when extending JavaScript Promise扩展 JavaScript Promise 时出错
【发布时间】:2016-05-11 12:18:57
【问题描述】:

我有一个接受回调的 Worker 类,但我想通过将其设置为 Promise 来删除回调,所以我可以这样做 new Worker(stuff, otherStuff).then(function() { ... });

为此,我使用了extends 关键字。

起初,我在this.a = a; 分配时收到ReferenceError: this is not defined 错误,但我发现那是因为我必须调用super();

现在,它在this.resolve({output: 'ok'}); 行给出了TypeError: this.resolve is not a function,所以我尝试强制添加this.resolvethis.reject 函数,但错误不会消失。

这是(高度简化的)代码:

class Worker extends Promise {
    constructor(a, b) {
        super((resolve, reject) => {
            console.log('inside super');
            this.resolve = resolve;
            this.reject = reject;
        });

        console.log('start constructing');

        this.a = a;
        this.b = b;

        console.log('A: ' + JSON.stringify(a));
        console.log('B: ' + JSON.stringify(b));

        this.doStuff();

        if (!this.status) {
            this.resolve({output: 'ok'});
        } else {
            this.reject('There was an error');
        }
    }

    doStuff() {}
}

let a = {x: 1};
let b = {z: 2};

console.log('before creation');
let w = new Worker(a, b);
console.log('after creation');
w.then(function() {
    console.log('done');
});

我正在使用节点 6.1.0,其中 appears 支持 Promise 子类化...我做错了什么?

【问题讨论】:

  • 实际上应该抛出的是this.resolve = resolve; - 因为thissuper 调用返回之前尚未初始化
  • 你能告诉我们你的实际代码吗?我不明白你为什么在这里继承 Promise 或者到底什么部分是异步的。
  • 实际代码使用了一个库(kue),它实现了一个异步队列,并用它来处理一些“测试”。处理完毕,调用this.resolve,如果某处有错误,调用this.reject
  • 这似乎不是继承Promise 的好理由。只需创建一个返回标准承诺的普通函数。
  • 实际代码可以在here找到,但请记住BatchEvaluator类仍然是旧版本(带有回调)

标签: javascript node.js es6-promise


【解决方案1】:

最佳做法是避免扩展原始类,因为它们会发生变化。扩展它们会将您自己的类置于浏览器/引擎的怜悯之下。

当您尝试扩展 Promise 类时,this 将不会在构造函数中定义,因为现在大多数引擎不支持子类化 Promise。

此外,工人不是承诺。工人应该工作并做出承诺。

一种解决方案是使用包装器或工厂模式而不是继承。

例如,您可以在您的Worker 类中定义一个getter promise,它会创建一个新的Promise 实例并返回它。

【讨论】:

  • 删除前两段,你会得到支持 :-) 原生类被设计为可扩展的,并且其规则定义明确。
  • @Bergi 我不是为了点赞而发帖。此外,由于本机类和任何本机代码、对象等都不是由用户自己编写的,它们受提供者的支配——例如那些编写 javascript/typescript 引擎的人。不管人们如何声称这样的类被设计为可扩展的 bla bla bla,人类本质上是不可信的。我学得很辛苦,所以不要试图说别的。
  • 所有 JS 代码都受引擎实现者和执行者的支配。本机类在 ECMAScript 语言规范中定义良好,没有理由不信任它。而且你不能在不使用任何内置函数的情况下编写有用的 JS 代码,因此没有理由相信类的可扩展性不如正则表达式对象的 exec 方法。
  • @Bergi Jul 3 规范是参考,不是实现。大多数情况下,规范远远领先于实际实施。结果,制作了polyfills。根据引擎限制,这些实现将遵循或不遵循规范。因此,即使 polyfill 完成了它们的工作,但这并不意味着它们能够逐字地达到规范。我已经学会了不信任任何文档的艰难方法。
猜你喜欢
  • 1970-01-01
  • 2014-12-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-27
  • 1970-01-01
相关资源
最近更新 更多