Nodejs异步函数原型链错误

时间:2018-03-10 05:03:10

标签: node.js asynchronous async-await prototype

此代码编译的原因

var Person =  function() {
console.log("CALLED PERSON")};

Person.prototype.saySomething = function() {
console.log("saySomething PERSON")};

var ape = new Person();
ape.saySomething();

并且此代码抛出错误无法设置未定义属性“saySomething”

var Person =  async function() {
console.log("CALLED PERSON")};

Person.prototype.saySomething = function() {
console.log("saySomething PERSON")};

var ape = new Person();
ape.saySomething();

2 个答案:

答案 0 :(得分:1)

使用async function() {}时,您声明了asynchronous function个对象。这与常规function对象不同。异步函数对象没有原型。

所以,当你尝试这样做时:

var Person =  async function() {
  console.log("CALLED PERSON")
};

Person.prototype.saySomething = function() {
  console.log("saySomething PERSON")
};

Person.prototypeundefined,因为prototype对象上没有asynchronous function。因此,尝试将某些内容分配给Person.prototype.saySomething会导致您看到错误,因为Person.prototypeundefined

这有一些逻辑,因为异步函数不能用作构造函数,因为异步函数总是返回一个promise,所以它不能像let obj = new f()那样返回一个新对象。因此,拥有.prototype属性没有任何意义,因为它不能以这种方式使用。

如果你真的想要异步创建一个对象,你总是可以创建一个async工厂函数,它返回一个用对象解析的promise。

答案 1 :(得分:1)

可以在原型链的末尾添加异步函数

请注意,这在nodejs 8.11.1 +。

中效果很好
// lets start with defining some cool async function who takes the time and 
// awaits a promise 

async function someCoolAsyncFunction() {
    // this let will be returned after timeout in a different value.
    let coolStuff = 'still boring';

    // do something cool which takes time 
    await new Promise((resolve, reject) => setTimeout(() => {
        coolStuff = 'an epiphany';
        resolve();
    }, 1000))
    return coolStuff;
}

// Now let's define the 'regular' prototype chain with it's boring functions.

function Person(p) { 
     this.constructorPropery = p;
     return this;
}

Person.prototype.notAsync = function() {
     // do something regular in the prototype chain
     console.log("Let's build some ",this.constructorPropery)
     this.kindOfPerson = 'Regular and boring'; 
     return this;   
}

// And now, lets add an async function to this chain

Person.prototype.someAsyncFunction = async function() {
    // you will still have access to 'this' in this function as long as the
    // previous function in the prototype chain returnes 'this'
    console.log('I used to be someone ',this.kindOfPerson);

    // Now, this is our time to shine, lets await something cool
    this.lifeChangingEvent = await someCoolAsyncFunction();
    console.log('Until I had ',this.lifeChangingEvent);
    a.kindOfPerson = 'enlightened';
    console.log('and now I am ', a.kindOfPerson);
    return this;
}

所以这会奏效:

new Person('charachter').notAsync().someAsyncFunction();

不会工作:

new Person('charachter').someAsyncFunction().notAsync();

如果您真的需要原型链外的'this'中的数据,您也可以这样做:

let myself = new Person('charachter').notAsync();
console.log('myself.kindOfPerson is: ',myself.kindOfPerson);
myself.someAsyncFunction(); 
console.log('myself.kindOfPerson now is: ',myself.kindOfPerson);

请务必记住哪个原型是哪个函数的异步函数,或者使用您自己的命名对流。