Javascript 如何在类函数中使其不为null?

Javascript 如何在类函数中使其不为null?,javascript,this,babeljs,Javascript,This,Babeljs,从下面的getPlanById函数中,我得到一个TypeError:无法读取null的属性“planReducer”错误。我尝试在构造函数和使用箭头函数中绑定此。两者似乎都不起作用。还有别的事情在起作用吗 require('dotenv').config(); const { RESTDataSource } = require('apollo-datasource-rest') import firebaseInitialize from '../../firebase_initialize

从下面的
getPlanById
函数中,我得到一个
TypeError:无法读取null的属性“planReducer”错误。我尝试在构造函数和使用箭头函数中绑定此
。两者似乎都不起作用。还有别的事情在起作用吗

require('dotenv').config();

const { RESTDataSource } = require('apollo-datasource-rest')
import firebaseInitialize from '../../firebase_initialize'
const firebase = firebaseInitialize()

class PlanData extends RESTDataSource {
  constructor() {
    super()
    this.baseURL = 'https://api.com/'
    this.getPlanById = this.getPlanById.bind(this)
  }
  willSendRequest(request) {
    console.log(this.context.headers)
    request.headers.set('Auth', this.context.headers.authorization);
  }
  planReducer(data) {
    return {
      id: data.plan.id,
      image: data.plan.image,
      title: data.plan.title
    }
  }
  getPlanById = async ({ planId }) => {
    const db = firebase.database()
    const ref = db.ref(`plans/${planId}`)
    ref.once("value", function(snapshot) {
      const data = snapshot.val()
      return this.planReducer(data)
    }).catch((e) => {
      console.log(e)
    });
  }
}

export default PlanData

引用了案例中的
函数(快照){…}
闭包

简单的方法是在闭包外部定义
父项
,然后使用
父项
,而不是

require('dotenv').config();

const { RESTDataSource } = require('apollo-datasource-rest')
import firebaseInitialize from '../../firebase_initialize'
const firebase = firebaseInitialize()

class PlanData extends RESTDataSource {
  constructor() {
    super()
    this.baseURL = 'https://api.com/'
    this.getPlanById = this.getPlanById.bind(this)
  }
  willSendRequest(request) {
    console.log(this.context.headers)
    request.headers.set('Auth', this.context.headers.authorization);
  }
  planReducer(data) {
    return {
      id: data.plan.id,
      image: data.plan.image,
      title: data.plan.title
    }
  }
  getPlanById = async ({ planId }) => {
    const parent = this;
    const db = firebase.database()
    const ref = db.ref(`plans/${planId}`)
    ref.once("value", function(snapshot) {
      const data = snapshot.val()
      return parent.planReducer(data)
    }).catch((e) => {
      console.log(e)
    });
  }
}
但是,您的
return parent.planReducer(data)
行可能也在做一些您不希望它做的事情:它只是在闭包中返回,而不是在
getPlanById
函数中返回

因此,要解决这个问题,请使用
async/await

require('dotenv').config();

const {RESTDataSource} = require('apollo-datasource-rest')
import firebaseInitialize from '../../firebase_initialize'

const firebase = firebaseInitialize()

class PlanData extends RESTDataSource {
    constructor() {
        super();
        this.baseURL = 'https://api.com/';
        this.getPlanById = this.getPlanById.bind(this)
    }

    willSendRequest(request) {
        console.log(this.context.headers);
        request.headers.set('Auth', this.context.headers.authorization);
    }

    planReducer(data) {
        return {
            id: data.plan.id,
            image: data.plan.image,
            title: data.plan.title
        }
    }

    getPlanById = async ({planId}) => {
        const parent = this;
        const db = firebase.database();
        const ref = db.ref(`plans/${planId}`);
        return await new Promise((resolve) => {
            ref.once('value', function (snapshot) {
                const data = snapshot.val();
                resolve(parent.planReducer(data));
            }).catch((e) => {
                console.log(e);
                // add some sensible error handling here
                resolve(null);
            });
        });

    }
}

如果希望
指向实例,请不要在方法中使用箭头函数。效果很好。谢谢