微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

ReactJS-axios.post

如何解决ReactJS-axios.post

我的reactjs中的axios.post调用出现同步问题。 我有一个输入区域,供用户选择要提交到axios.post的本地文件,该文件被转换为arraybuffer,然后通过axios调用发送给Microsoft Faces api。如果选择图像,则按分析按钮,同步将关闭,并尝试在没有数组缓冲区的情况下发出发布请求。如果我第二次单击它,它将正确显示该帖子。

我对等待和异步还很陌生,对我的问题的任何投入都会有很大的帮助。我曾考虑过使用布尔值标志,但想学习如何通过正确的设计更好地实现此功能

import React,{ useState } from "react";
import axios from "axios";
import { Button,Container,Row,Col } from "react-bootstrap";
import "../../styling/FacialRecognition.css";
import defaultimage from "../../assets/images/defaultimage.png";

function FacialRecognition() {
    const [image,setimage] = useState("");
    const [imageData,setimageData] = useState([]);
    const [responseData,setResponseData] = useState([]);
    const [dataLoad,setDataLoad] = useState(false);


//translates the local file to the array buffer,and sets the imageData.
    function TranslateImagetoArrayBuffer(imagetoTranslate) {
        let reader = new FileReader();
        reader.readAsArrayBuffer(imagetoTranslate);
        reader.onloadend = () => {
        setimageData(reader.result);
        };
    }


//Makes the call with the url,options,and the arraybuffer.
    function ProcessImage(localImage) {
        TranslateImageArrayBuffer(localImage);
        console.log("ImageData: " + imageData);
      
        var subscriptionKey = "<subscriptionkey>";
        var uriBase =
            "https://(urlgoeshere).cognitiveservices.azure.com/face/v1.0/detect";
        const options = [
            "returnFaceId=true","returnFaceLandmarks=true","returnFaceAttributes=age,gender,headPose,smile,facialHair,glasses,emotion,hair,makeup,accessories",];

        uriBase = uriBase.concat("?",options.join("&"));
        // Perform the REST API call.

        axios
            .post(uriBase,imageData,{
                headers: {
                    "Content-Type": "application/octet-stream","Ocp-Apim-Subscription-Key": subscriptionKey,},})
            .then(function (response) {
                // display the image.

                var blob = new Blob([imageData]);
                var url = URL.createObjectURL(blob);
                setDataLoad(true);
                document.querySelector("#sourceImage").src = url;
                console.log("Status text: " + response.status);
                console.log("Status text: " + response.statusText);

                console.log(response.data);
                setResponseData(response.data);
            })
            .catch(function (error) {
                console.log(error);
            });
    }

    let value = responseData.map((e) => JSON.stringify(e,null,2));
    return (
        <div>
            <Container fluid="xl">
                <Row>
                    <Col xs="auto">
                        <p>
                            Select a local image,and then click the <b>Analyze face button.</b>
                        </p>
                    </Col>
                </Row>
                <Row>
                    <Col x="auto">
                        <label>Image to analyze: </label>
                        <input
                            type="file"
                            name="inputimage"
                            id="inputimage"
                            autoComplete="off"
                            accept="image/png,image/jpeg"
                            onChange={(e) => setimage(e.target.files[0])}
                            style={{ width: "60%",marginLeft: "1vw" }}
                        />
                        <Button
                            variant="info"
                            onClick={() => ProcessImage(image)}>
                            Analyze face
                        </Button>
                    </Col>
                </Row>
                <Row style={{ marginTop: "2vw" }}>
                    <Col xs="6">
                        <label>
                            <strong>Response</strong>
                        </label>
                    </Col>
                    <Col xs="auto">
                        <label>
                            <strong>Source Image</strong>
                        </label>
                    </Col>
                </Row>
                <Row>
                    <Col>
                        {dataLoad ? (
                            <textarea
                                id="responseTextArea"
                                className="UIInput"
                                style={{ width: "100%",height: "429px" }}
                                value={value}
                                readOnly={true}
                                disabled="disabled"></textarea>
                        ) : (
                            <textarea
                                id="responseTextArea"
                                className="UIInput"
                                style={
                                    dataLoad
                                        ? { display: "none" }
                                        : { width: "100%",height: "auto" }
                                }
                                defaultValue="This field will display analyzed data on the image"
                                readOnly={true}
                                disabled="disabled"></textarea>
                        )}
                    </Col>
                    <Col xs="6">
                        {dataLoad ? (
                            <img
                                id="sourceImage"
                                alt=""
                                style={
                                    dataLoad
                                        ? { width: "80%" }
                                        : { display: "none" }
                                }
                            />
                        ) : (
                            <img
                                id="defaultimage"
                                src={defaultimage}
                                alt=""
                                style={
                                    dataLoad
                                        ? { display: "none" }
                                        : { width: "80%" }
                                }
                            />
                        )}
                    </Col>
                </Row>
            </Container>
        </div>
    );
}

export default FacialRecognition;

我还尝试将TranslateImagetoArrayBuffer设置为异步函数,并将axios调用置于.then(response => {axios.post...})内,但不走运。

编辑:我也尝试过将我的Translate函数内容包装在一个Promise中。

async function TranslateImagetoArrayBuffer(imagetoTranslate) {
    return new Promise((resolve,reject) => {
        var reader = new FileReader();

        reader.onload = () => {
            setimageData(reader.result);
            resolve(imageData);
        };

        reader.onerror = () => {
            reject(reader.result);
        };
        reader.readAsArrayBuffer(imagetoTranslate);
    });
}

,并在我的ProcessImage函数中使用const contents = await TranslateImagetoArrayBuffer(localImage);行以等待该值。仍然有同步问题。

解决方法

我无法使其与异步一起工作,所以我将函数onChange移到了用于输入文件的位置,以将图像转换为数组缓冲区,而不是在ProcessImage()中进行调用。

                    <input
                        type="file"
                        name="inputImage"
                        id="inputImage"
                        autoComplete="off"
                        accept="image/png,image/jpeg"
                        onChange={(e) =>{ TranslateImageToArrayBuffer(e.target.files[0]);setImage(e.target.files[0]) }}
                        style={{ width: "60%",marginLeft: "1vw" }}
                    />
                    <Button
                        variant="info"
                        onClick={() => ProcessImage()}>
                        Analyze face
                    </Button>

这避免了进行异步设置的需要。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。