异步函数内部的异步函数返回未定义的值

时间:2019-12-20 14:40:37

标签: javascript class asynchronous

我正在JS类中工作,无法弄清楚colors.ColorCheck(0).ColorCodecolors.ColorCheck(0).Color返回undefined值的原因。

如您所见,“ 0”作为函数ColorCheck的参数传递,并在函数this.ColorCodethis.Color中使用。

我敢肯定,在主函数(this.ColorCode)中声明两个函数(this.ColorColorCheck时会丢失一些东西,但是我看不到什么

我是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

3 个答案:

答案 0 :(得分:2)

您的ColorCheck函数未返回任何内容,因此,以colors.ColorCheck(0)调用该函数时,返回的是undefined

我认为与其设置this.ColorCodethis.Color(而不是this引用Color实例),您实际上想要的是返回带有两个键的对象,{ {1}}和ColorCode,其值为两个curried异步函数,将在调用时使用提供的Color发出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(', '));
})();

您也可以将axios调用移至.as-console-wrapper { max-height: none !important; }函数(而不使其变为ColorCode),这样就不必每次调用两个返回函数中的任何一个时都发出额外的请求: / p>

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(', '));
})();

答案 1 :(得分:1)

欢迎光临!只需记住也awaitthen主机异步功能

示例:

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分配为a(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中的this文章。当前,您的值存储在class Colors上下文中,而不仅仅是使用const将它们存储在函数的上下文中。例如:
const info = await axios...
const c = info.map(...);
return c;

答案 2 :(得分:-1)

您想使用string literals,但您将其定义为普通字符串:

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

您应该更改为此:

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