javascript - 如何使用异步函数?

标签 javascript node.js mongodb axios

目前正在开发一个从客户端服务器向后端服务器发出 axios 请求的应用程序。

有时应用程序会正确更新,有时会滞后/直到下一个请求才会更新。知道为什么吗?

我的代码有问题吗?我会尝试添加所有相关的内容。

该应用程序是一个杂货 list ,用户只需通过 Google oauth 登录即可。 然后,他们从 React State 和 MongoDB 数据库中添加/删除项目。

每次添加/删除项目时都会从数据库中提取列表的状态。

应用组件

import React from 'react';
import ListForm from './ListForm';
import ListItem from './ListItem';
import * as helpers from '../helpers';

class App extends React.Component{
  state = {
    currentUser: {},
    items: []
  }

  componentDidMount() {
    helpers.fetchUser()
      .then(data => {
        this.setState({
          currentUser: data,
          items: data.shoppingList
        }, () => {
          console.log(this.state)
        });
      });
  }

  // Handle adding new items
onSubmit = (item) => {
  this.setState({items: this.state.items.concat([item])});
  helpers.addItem(item)
    .then(
      helpers.fetchUser()
        .then(data => {
          this.setState({
            currentUser: data,
            items: data.shoppingList
          }, () => {
            console.log(this.state);
          });
        })
      )
  }

  // Handle deletion of items
  onDelete = (deleteItem) => {
    helpers.removeItem(deleteItem)
      .then(
        helpers.fetchUser()
          .then(data => {
            this.setState({
              currentUser: data,
              items: data.shoppingList
            }, () => {
              console.log(this.state);
            })
          })
      )
  }

  renderContent = () => {
    const shoppingList = this.state.currentUser.shoppingList;
    const currentUser = this.state.currentUser;

    if(!currentUser.googleId) {
       return (
         <div className="row justify-content-center">
           <div>
             <a href="/auth/google" className="btn btn-primary"><i className="fa fa-google" />  Sign in with Google</a>
           </div>
         </div>
       );
    } else if(shoppingList === undefined || shoppingList.length < 1) {
        return (
          <div className="row justify-content-center">
            <h5>Add your first item!</h5>
          </div>
        );
    } else {
        return (
          <div>
            {this.state.items.map((item, index) =>
              <ListItem
                {...item}
                key={index}
                id={index}
                currentUser={this.state.currentUser}
                onDelete={this.onDelete}
              />
            )}
          </div>
        );
    }
  }

  render() {
    return (
      <div className="container row offset-4">
        <div className="jumbotron col-sm-6">
          <ListForm
            currentUser={this.state.currentUser}
            items={this.state.items}
            onSubmit={this.onSubmit}
          />
          {this.renderContent()}
        </div>
      </div>
    );
  }
};

export default App;

列表组件

import React from 'react';

class ListForm extends React.Component {
  state = {
    value: ''
  }

  // Handle the submission of a new item to database and state.
  handleSubmit = e => {
    e.preventDefault();

    this.props.onSubmit({name: this.state.value});
    this.setState(prevState => ({value: ''}));
  }

  // Handle any changes within the input.
  onChange = e => {
    this.setState({value: e.target.value});
  }

  render() {
    return (
      <div className="col-xs-9">
          <h3>Grocery List</h3>
        <form className="form-control" onSubmit={this.handleSubmit}>
          <input style={{display: "inline", width: "60%", height: "2em"}} className="form-control" type="text"
            value={this.state.value}
            onChange={this.onChange}
            required
            />
          <button className="btn btn-success btn-sm float-right">Add item</button>
        </form>
        <div style={{marginTop: "10%"}}>
        </div>
      </div>
    );
  }
}

export default ListForm;

Helpers.js(发出请求的地方)

import axios from 'axios';

export const fetchUser = async () => {
  const resp = await axios.get('/api/current_user');

  return resp.data;
}

export const addItem = async (newItem) => {
  const resp = await axios.post("/api/addItem", newItem);

  return resp.data;
}

export const removeItem = async (deleteItem) => {
  axios.delete("/api/removeItem", {data: {item: deleteItem}});
}

涉及用户数据的路由

const mongoose = require('mongoose');
const User = require('../models/userSchema');

module.exports = (app) => {
  app.post('/api/addItem', async (req, res) => {
    const item = await req.body;

    req.user.shoppingList.push(item);
    req.user.save();

    console.log(req.user);

    res.send(item);
  });

  app.delete('/api/removeItem', (req, res) => {
    const itemName =  req.body.item;
    console.log(itemName);
    const index = req.user.shoppingList.findIndex(i => i.name === itemName);
    console.log(index);

    req.user.shoppingList.splice(index, 1);
    req.user.save();

    console.log(req.user);

    res.send(itemName);
  });
};

如果我需要添加任何内容以使这一点更清楚,请告诉我!

最佳答案

查看代码时很难说,因为 .then() 后面没有 .catch 子句。这将是第一个要检查的地方:如果您的请求有时失败怎么办?此外,React devtools 扩展非常适合在运行时检查状态 - 如果这不是 promise 问题,您当然可以用它来确定它。

关于javascript - 如何使用异步函数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47784814/

相关文章:

javascript - Vue-bootstrap 卡不显示登机

ruby - 如何使用 GridFS 上传文件并将其直接保存到 MongoDB

c++ - MongoCxx 3.1.0 如何关闭连接?

mongodb - MongoDB和Redis有什么区别?

javascript - 使不可编辑的列对于新添加的行可编辑

javascript - 追加错误动态表

javascript - datejs TimeSpan 和 TimePeriod 问题

node.js - NodeJS 事件是否会传递到其父函数?

javascript - 使用 NodeJS 和 FFMpeg Fluent Api 的视频字幕

javascript - Node.js 异步文件 I/O