компонент класса, не ожидающий возврата функции

#javascript #next.js

#javascript #next.js

Вопрос:

у меня есть функция, которая извлекает и сортирует данные из api ( getactivity() ), а затем возвращает отсортированные данные в правильном формате ( answer1 ). но я столкнулся с проблемой.. когда я пытаюсь запустить функцию, чтобы получить данные, она продолжает ничего не возвращать..

вот полный код,

 import React, { Component, Fragment } from 'react';
import axios from 'axios';
import Pusher from 'pusher-js';
import Stats from '../../components/Stats';
import Layout from '../../components/Layout';

const choices = ['Monday', 'Tusday', 'Wensday', 'Thursday', 'Firday'];

let curr = new Date 
let week = []

for (let i = 1; i <= 7; i  ) {
  let first = curr.getDate() - curr.getDay()   i 
  let day = new Date(curr.setDate(first)).toISOString().slice(0, 10)
  week.push(day)
}

// console.log(week)

function getactivity() {

    axios.get('/api/profiles/stats')
      .then(response => {
        const activty = response.data["Drinks"]

        var o = {};
        activty.forEach((i) => {
          var Date = i.Date;
          i.count = parseInt(i.count)
          if (!o[Date]) {
            return o[Date] = i
          }
          return o[Date].count = o[Date].count   i.count
        })

        var res = []
        Object.keys(o).forEach((key) => {
         res.push(o[key])
        })

        var answer1 = ""
        for (const x of res) {
            if(week.includes(x.Date)) {
                answer1 = answer1   "["   x.Date   "]"   ": "   x.count   ", "
            }
        }
        console.log("return: "   answer1)
        return answer1
    }, error => {
    console.log(error);
  });
}

console.log("act: "   getactivity())

class IndexPage extends Component {

    state = { answers: getactivity() }

  render() {

    return (
      <Layout pageTitle="AA Drinking activity">
        <main className="container-fluid position-absolute h-100 bg-light">
          <div className="row position-absolute w-100 h-100">
            <section className="col-md-5 position-relative d-flex flex-wrap h-100 align-items-start align-content-between bg-white px-0">
                <Stats choices={choices} stats={this.state.answers} />
            </section>

          </div>
        </main>
      </Layout>
    );
  }

};

export default () => (
    <Fragment>
        <IndexPage />
        <style global jsx>{`

            .custom-control-label {
                background: transparent;
                color: #999;
                font-size: 2rem;
                font-weight: 500;
                cursor: pointer;
                line-height: 2.25rem;
            }

            .custom-control-label:before, .custom-control-label:after {
                top: 0;
                left: -10px;
                height: 2.25rem;
                width: 2.25rem;
                cursor: pointer;
                box-shadow: none !important;
            }

            .custom-control-label.checked {
                color: #007bff !important;
            }

            button.btn {
                letter-spacing: 1px;
                font-size: 1rem;
                font-weight: 600;
            }

        `}</style>
    </Fragment>
);
 

порядок console.log() действительно показывает show так, как я бы подумал, что это должно быть,
он печатается в порядке

действие: не определено

возвращение: [2020-12-08]: 10, [2020-12-09]: 7, [2020-12-10]: 4, [2020-12-11]: 3,

я бы предположил, что возврат будет напечатан первым.

Комментарии:

1. поскольку вы ничего не возвращаете в getactivity — конечно, результат будет undefined

2. @Bravo в getactivity есть возврат

3. нет, в функции обратного вызова внутри этой функции есть возврат, из которого вы вообще ничего не возвращаете getactivity — вам нужно будет выяснить, как использовать асинхронность — в stack есть хороший вопрос о том, как использовать данные из асинхронного вызова

Ответ №1:

вы получаете эту ошибку, потому что javascript запускается асинхронно. Он не ожидает ответа от сервера (созданного вашим вызовом axios), чтобы продолжить его выполнение. В вашем случае решением было бы поместить код, который вы хотите запустить, в цепочку, затем вот так:

 axios.get('/api/profiles/stats')
  .then(response => {
    // the code run directly after the axios call...
  }.then(activity=>{
    console.log("act: " activity);
  });
 

если вы хотите использовать getActivity внутри функции, вы можете использовать async / await . эта ссылка должна быть полезной https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Asynchronous/Async_await