Я работаю в классе JS и не могу понять причину, по которой colors.ColorCheck(0).ColorCode и colors.ColorCheck(0).Color возвращают undefined значения.

Как видите, «0» передается в качестве аргумента функции ColorCheck и используется внутри функций this.ColorCode и this.Color.

Я почти уверен, что что-то упустил при объявлении двух функций (this.ColorCode и this.Color) внутри главной функции (ColorCheck), но я не вижу, что именно.

Я новичок в JS, поэтому я не удивлюсь, если решение кажется очевидным для вас, ребята.

class Colors {

    constructor(){}

    async ColorCheck(ID){
        this.ColorCode = (async()=>{
            this.info = await axios.get ('https://.../${ID}.json')
            this.CodeC = this.info.map(t=>t.colorcode)
            return this.CodeC
        })
        this.Color = (async()=>{
            this.info = await axios.get ('https://.../${ID}.json')
            this.C = this.info.map(t=>t.color)
            return this.C
        })
    }
}

const colors = new Colors()
colors.ColorCheck(0).ColorCode
colors.ColorCheck(0).Color
1
Drun 20 Дек 2019 в 17:40

3 ответа

Лучший ответ

Ваша ColorCheck функция ничего не возвращает, поэтому, вызывая ее как colors.ColorCheck(0), она возвращает undefined.

Я думаю, что вместо установки this.ColorCode и this.Color, где this ссылается на экземпляр Color, вам на самом деле нужно вернуть объект с двумя ключами, {{X4} } и Color, значения которых равны двум curried async функции, которые будут вызывать GET запрос с предоставленным id при вызове.

Это, вероятно, будет выглядеть примерно так:

// Just mocking axios for this example:

const axios = {
  get: (url) => new Promise((resolve, reject) => {
    console.log(`Making a request to ${ url }...`);
    
    setTimeout(() => {
      resolve([{
        colorCode: '#F00',
        color: 'red',
      }, {
        colorCode: '#0F0',
        color: 'green',
      }, {
        colorCode: '#00F',
        color: 'blue',
      }]);
    }, 2000);
  }),
};

class Colors {
  constructor() { }
  
  ColorCode(id) {
    return {
      ColorCode: (async () => {
        const info = await axios.get(`https://.../${ id }.json`);
        
        return info.map(t => t.colorCode);
      }),

      Color: (async () => {
        const info = await axios.get(`https://.../${ id }.json`);
        
        return info.map(t => t.color);
      }),
    };
  }
}

const colors = new Colors();
const returnedValue = colors.ColorCode(0);

(async () => {
  console.log((await returnedValue.ColorCode()).join(', '));
  console.log((await returnedValue.Color()).join(', '));
})();
.as-console-wrapper {
  max-height: none !important;
}

Вы также можете переместить вызов axios в функцию ColorCode (не делая ее async), чтобы не делать дополнительный запрос каждый раз, когда вызывается любая из двух возвращаемых функций:

// Just mocking axios for this example:

const axios = {
  get: (url) => new Promise((resolve, reject) => {
    console.log(`Making a request to ${ url }...`);
    
    setTimeout(() => {
      resolve([{
        colorCode: '#F00',
        color: 'red',
      }, {
        colorCode: '#0F0',
        color: 'green',
      }, {
        colorCode: '#00F',
        color: 'blue',
      }]);
    }, 2000);
  }),
};

class Colors {
  constructor() { }
  
  ColorCode(id) {  
    // Note there no `await` here:
    const infoPromise = axios.get(`https://.../${ id }.json`);
    
    return {
      ColorCode: (async () => {
        return (await infoPromise).map(t => t.colorCode);
      }),

      Color: (async () => {
        return (await infoPromise).map(t => t.color);
      }),
    };
  }
}

const colors = new Colors();
const returnedValue = colors.ColorCode(0);

(async () => {
  console.log((await returnedValue.ColorCode()).join(', '));
  console.log((await returnedValue.Color()).join(', '));
})();
.as-console-wrapper {
  max-height: none !important;
}
2
Danziger 20 Дек 2019 в 15:16

Вы хотите использовать строковые литералы, но вы определяя как обычную строку:

this.info = await axios.get ('https://.../${ID}.json');

Вы должны изменить это:

this.info = await axios.get (`https://.../${ID}.json`);
-1
Ricardo Rocha 20 Дек 2019 в 14:49

Добро пожаловать! просто не забудьте await или then асинхронную функцию хоста

Пример:

async function a() {
  return await http.get(...)
}
a() // undefined (promise awaiting resolve)
await a(); // expected value
a().then(value => console.log(value)) // expected value

В случае function a() вы можете просто вернуть саму асинхронную задачу, которую вам все равно придется решать позже:

function a() {
  return http.get(...)
}

a() // undefined (promise awaiting resolve)
await a() // expected value
a().then(...) // expected value

Также: - вы назначили this.ColorCode функцией (n асинхронной), что означает, что вам придется вызывать ее, чтобы получить значение, перенастроенное на нее:

await Colors.ColorCheck('0'); // Colors.ColorCode and Colors.Color are now being assigned
await Colors.ColorCode(); // this.CodeC is being assigned to the class Colors + returned. which means from now on Colors.CodeC is also accessible
await Colors.Color() // assigns Colors.C a value + returns it. from now on Colors.C is also accessible

note that Colors.info is also assigned and overridden each time you call any of the functions (Colors.ColorCode / Colors.Color)

  • ключевое слово this, скорее всего, используется неправильно: обратитесь к эта статья в MDN. в настоящее время ваши значения хранятся в контексте class Colors, а не просто хранятся в контексте функции, используя const. например:
const info = await axios...
const c = info.map(...);
return c;
1
shukar 20 Дек 2019 в 15:11