如何减慢Express Server的响应速度,以允许react-admin getOne()函数正常工作? [英] How do I slow down my express server response to allow the react-admin getOne() function to work?

查看:47
本文介绍了如何减慢Express Server的响应速度,以允许react-admin getOne()函数正常工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我创建了VetCreate和VetEdit函数来创建新记录,然后分别编辑该记录(下面的代码).我遇到的问题是,成功返回了create响应,但是在获取记录的请求中没有填充新创建的ID.

I have created VetCreate and VetEdit functions to create a new record and then edit that record respectively (code below). The problem I have is the successful create response is returned but the newly created id isn't populated in the request to fetch the record.

我在需要的地方放置了 async/await 关键字,但是登录到控制台的详细信息清楚地表明某些内容无法正常工作.如果我在返回列表屏幕后尝试编辑记录,则该API会按预期工作并返回详细信息.

I have async/await keywords in place where I think they need to be but the details logged to the console clearly indicate something isn't working as it should. If I try to edit a record after returning to the list screen, the API works as expected and returns the details.

我已经添加了所有可以想到的代码和屏幕截图,但是如果需要更多内容,请询问.

I've added all the code and screenshots I can think of but if anything more is required, please ask.

VetCreate
export const VetCreate = (props) => (
  <Create title="Credit Application" aside={<CreateAside />} {...props}>
    <TabbedForm toolbar={<VetCreateToolbar />} redirect="show">
      <FormTab label="applicant">
        <DateInput disabled label="Date Created" source="DateCreated" defaultValue={moment(new Date()).format('YYYY-MM-DD hh:mm:ss')} />
        <TextInput disabled label="Agent Name" defaultValue={sessionStorage.getItem('foneBookUser')} source="CreatedBy" />
        <TextInput label="First Name" defaultValue={'Adam'} source="FirstName" validate={validateLength} />
        <TextInput label="Surname" defaultValue={'Smith'} source="Surname" validate={validateLength} />
        <TextInput label="RSA ID Number" defaultValue={4567890987654} source="IDNumber" validate={validateID} />
        <SelectInput label="Sex" defaultValue={'M'} source="sex" choices={[
            { id: 'M', name: 'Male' },
            { id: 'F', name: 'Female' },
        ]} validate={validateSex}/>
        <TextInput label="Age of Applicant" defaultValue={45} source="ApplicantAge" validate={validateAge} />
        <TextInput label="Business Partner" defaultValue={''} source="BusinessPartner" />
        <TextInput label="Sales Person" defaultValue={'Spiderman'} source="SalesPerson" validate={validateLength} />
        <TextInput label="Cell Phone Number" defaultValue={'345678'} source="CellNumber" validate={validateLength} />
        <TextInput label="Email Address" defaultValue={'adam@email.com'} source="Email" validate={validateEmail} />
      </FormTab>
      <FormTab label="bureau">
        <TextInput label="Bureau Score" defaultValue={123} source="BureauScore" validate={validateBureauScore} />
        <TextInput label="Gross Monthly Income" defaultValue={30000} source="GrossMonthlyIncome" validate={validateGross} />
        <TextInput label="Total Monthly Instalment" defaultValue={3000} source="TotalMonthlyInstalment" validate={validateInstal} />
        <TextInput label="Home Postcode" defaultValue={'1122'} source="HomePostCode" validate={validateCode} />
        <TextInput label="Number of Properties" defaultValue={11} source="NumProperties" validate={validateNumber} />
        <TextInput label="Number of Companies" defaultValue={31} source="NumCompanies" validate={validateNumber} />
      </FormTab>
    </TabbedForm>
  </Create>
);

VetEdit
export const VetEdit = props => {
  const classes = useStyles();
  return (
    <Edit aside={<EditAside />} {...props}>
        <SimpleForm toolbar={<VetEditToolbar />} warnWhenUnsavedChanges>
          <TextInput disabled label="First Name" source="FirstName" formClassName={classes.inlineBlock} />
          <TextInput disabled label="Surname" source="Surname" formClassName={classes.inlineBlock} />
          <TextInput disabled label="RSA ID Number" source="IDNumber" formClassName={classes.inlineBlock} />
          <TextInput disabled source="Sex" formClassName={classes.inlineBlock} />
          <NumberInput disabled source="ApplicantAge" formClassName={classes.inlineBlock} />
          <TextInput disabled source="CellNumber" formClassName={classes.inlineBlock} />
          <TextInput disabled source="Email" formClassName={classes.inlineBlock} />
          <TextInput disabled source="BusinessPartner" formClassName={classes.inlineBlock} />
          <TextInput disabled source="SalesPerson" formClassName={classes.inlineBlock} />
          <TextInput disabled source="HomePostCode" formClassName={classes.inlineBlock} />
          <NumberInput disabled source="NumProperties" formClassName={classes.inlineBlock} />
          <NumberInput disabled source="NumCompanies" formClassName={classes.inlineBlock} />

          <NumberInput disabled source="GrossMonthlyIncome" formClassName={classes.inlineBlock} />
          <NumberInput disabled source="TotalMonthlyInstalment" formClassName={classes.inlineBlock} />
          <NumberInput disabled source="BureauScore" formClassName={classes.inlineBlock} />

          <SelectInput label="ID Verified" source="IDVerified" choices={[
            { id: 'N', name: 'No' },
            { id: 'Y', name: 'Yes'}
          ]} formClassName={classes.inlineBlock} />
          <SelectInput label="Debt Review" source="DebtReview" choices={[
            { id: 'N', name: 'No' },
            { id: 'Y', name: 'Yes'}
          ]} formClassName={classes.inlineBlock} />
          <SelectInput label="Poor Payment Profile" source="PoorPaymentProfile" choices={[
            { id: 'N', name: 'No' },
            { id: 'Y', name: 'Yes'}
          ]} formClassName={classes.inlineBlock} />
          <SelectInput label="Adverse" source="Adverse" choices={[
            { id: 'N', name: 'No' },
            { id: 'Y', name: 'Yes'}
          ]} formClassName={classes.inlineBlock} />
          <SelectInput label="Fraud Suspected" source="SuspectFraud" choices={[
            { id: 'N', name: 'No' },
            { id: 'Y', name: 'Yes'}
          ]} formClassName={classes.inlineBlock} />

          <TextInput label="ID Validated" source="IDValidated" formClassName={classes.inlineBlock} />
          <TextInput label="Bank Statement Validated" source="BankStatementValidated" formClassName={classes.inlineBlock} />
          <TextInput label="Payslip Validated" source="PayslipValidated" formClassName={classes.inlineBlock} />
          <TextInput label="Proof of Residence Validated" source="ResProofValidated" formClassName={classes.inlineBlock} />
        </SimpleForm>
    </Edit>
  )
};

DataProvider.js
import { fetchUtils } from 'react-admin';
import { stringify } from 'query-string';

const apiUrl = 'http://localhost:8081';

const httpClient = (url, options = {}) => {
    if (!options.headers) {
        options.headers = new Headers({
            'Accept': 'application/json',
            'Content-Type': 'application/json'
        });
    }
    // add your own headers here
    options.headers.set(
      'X-Custom-Header',
      'Access-Control-Allow-Headers',
      'Access-Control-Allow-Origin',
      '*',
    );
    //console.log('4 options: ', options);
    return fetchUtils.fetchJson(url, options);
};

export default {
  getList: (resource, params) => {
    //console.log('params: ', params);
      const { page, perPage } = params.pagination;
      const { field, order } = params.sort;
      const query = {
          sort: JSON.stringify([field, order]),
          range: JSON.stringify([(page - 1) * perPage, page * perPage - 1]),
          filter: JSON.stringify(params.filter),
      };
      const url = `${apiUrl}/${resource}?${stringify(query)}`;
      //console.log('url: ', url);

      return httpClient(url).then(({ headers, json }) => ({
          data: json,
          total: parseInt(headers.get('content-range').split('/').pop(), 10),
      }));
  },

  getOne: (resource, params) =>
        httpClient(`${apiUrl}/${resource}/${params.id}`).then(({ json }) => ({
            data: json,
        })),

    getMany: (resource, params) => {
        const query = {
            filter: JSON.stringify({ id: params.ids }),
        };
        const url = `${apiUrl}/${resource}?${stringify(query)}`;
        return httpClient(url).then(({ json }) => ({ data: json }));
    },

    getManyReference: (resource, params) => {
        const { page, perPage } = params.pagination;
        const { field, order } = params.sort;
        const query = {
            sort: JSON.stringify([field, order]),
            range: JSON.stringify([(page - 1) * perPage, page * perPage - 1]),
            filter: JSON.stringify({
                ...params.filter,
                [params.target]: params.id,
            }),
        };
        const url = `${apiUrl}/${resource}?${stringify(query)}`;

        return httpClient(url).then(({ headers, json }) => ({
            data: json,
            total: parseInt(headers.get('content-range').split('/').pop(), 10),
        }));
    },

    update: (resource, params) =>
        httpClient(`${apiUrl}/${resource}/${params.id}`, {
            method: 'PUT',
            body: JSON.stringify(params.data),
        }).then(({ json }) => ({ data: json })),

    updateMany: (resource, params) => {
        const query = {
            filter: JSON.stringify({ id: params.ids}),
        };
        return httpClient(`${apiUrl}/${resource}?${stringify(query)}`, {
            method: 'PUT',
            body: JSON.stringify(params.data),
        }).then(({ json }) => ({ data: json }));
    },

    create: (resource, params) =>
        httpClient(`${apiUrl}/${resource}`, {
            method: 'POST',
            body: JSON.stringify(params.data),
        }).then(({ json }) => ({
            data: { ...params.data, id: json.id },
        })),

    delete: (resource, params) =>
        httpClient(`${apiUrl}/${resource}/${params.id}`, {
            method: 'DELETE',
        }).then(({ json }) => ({ data: json })),

    deleteMany: (resource, params) => {
        const query = {
            filter: JSON.stringify({ id: params.ids}),
        };
        return httpClient(`${apiUrl}/${resource}?${stringify(query)}`, {
            method: 'DELETE',
            body: JSON.stringify(params.data),
        }).then(({ json }) => ({ data: json }));
    }
};

Vet API
Vet.createVet = async function(newVet, result) {
  console.log('newVet: ', newVet);
  await sql.query("INSERT INTO vets set ?", newVet, function(err, res) {
    if(err) {
      console.log('err: ', err);
      result(err, null);
    } else {
      console.log('res.insertId: ', res.insertId);
      result(null, res.insertId)
    }
  });
};

Vet.getVetById = async function (VetId, result) {
  console.log('getVetById: ', VetId);
  await sql.query("Select * from vets WHERE id = ?", VetId, function (err, res) {
    if(err) {
      console.log("error: ", err);
      result(null, err);
    } else {
      console.log('vets : ', res);
      result(null, res);
    }
  });
};

推荐答案

await 仅在您 await 诺言时才有用.像这样的语句:

await only does something useful when you await a promise. Statements like this:

await sql.query("INSERT INTO vets set ?", newVet, function(err, res) {...});

不是在等待诺言.该查询不返回承诺.该操作的结果仅出现在该回调中,而不出现在任何返回的promise中,因此 await 与该事件无关.在 await 中没有魔术可以以某种方式知道何时完成普通回调.不, await 是基于诺言的,如果您不兑现诺言,则无事可做(不等待任何事情).

are NOT awaiting a promise. That query does not return a promise. The result of that operation comes only in that callback, not in any returned promise so await has nothing to do. There is no magic in await that somehow knows when the plain callback is done. No, await operates on a promise and if you don't give it a promise, it has nothing to do (doesn't wait for anything).

相反,您需要使用不使用回调的数据库操作,但是如果您想对它们使用 await ,则应返回promise.

Instead, you need to use database operations that DON'T use callbacks, but instead return promises if you want to use await with them.

如果您使用的是mysql,请参见 mysql2 支持承诺,然后重写所有数据库语句以使用返回的承诺从中获取结果,并且不通过数据库调用普通回调.

If you're using mysql, see mysql2 for promise support and then rewrite all your database statements to use the returned promise to get the results from and do not pass the database call a plain callback.

这篇关于如何减慢Express Server的响应速度,以允许react-admin getOne()函数正常工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆