异步循环的第一次迭代会产生错误

时间:2017-11-01 18:30:33

标签: javascript reactjs asynchronous

我正在尝试获取媒体文件数据以加载到我的应用程序。我需要按顺序进行多个ajax调用。

问题:我收到错误说"无法读取属性' map'未定义"。我在某处的render方法中映射auto_video_jobs_array。

下面的代码显示了我如何按顺序执行ajax异步调用并设置状态current_auto_video_jobs。在最后一次ajax调用结束时,我可以控制打印状态current_auto_video_jobs的值,并且可以看到它中有对象。

(为了让我更容易理解,我也在我的问题中显示变量和状态声明)

var auto_video_jobs_array = [];
var auto_video_jobs_urls = [];



state = {
        MediaFiles: [],
        fileURLS: [],
        current_auto_video_jobs: [[{job_type:"", eta:0}],[{job_type:"", eta:0}],[{job_type:"", eta:0}],[{job_type:"", eta:0}],[{job_type:"", eta:0}],[{job_type:"", eta:0}],[{job_type:"", eta:0}],[{job_type:"", eta:0}],[{job_type:"", eta:0}],[{job_type:"", eta:0}]],
        current_auto_video_jobs_urls: [],
        loader: true
    };



componentDidMount = () => {

        var that = this;

        this.init_get_media_files();

       refreshIntervalId = setInterval(this.get_process_status.bind(this), 60000);    //new

    }

init_get_media_files() {

        var that = this;
        var URL_array = [];

        auto_video_jobs_urls = [];


        var settings = {
            "async": true,
            "crossDomain": true,
            "url":url,
            "method": "GET",
            "headers": {
                Authorization: "Token " + that.props.token_Reducer.token
            },
            success: function (response, textStatus, jQxhr) {
                response.results.map((item, i) => {
                    URL_array.push(item.url)

                    auto_video_jobs_urls.push(item.latest_process_status)//new
                })
            },
        }
        $.ajax(settings).done((response) => {


            //alert("yo");
            that.setState({
                MediaFiles: response.results,
                fileURLS: URL_array,

                current_auto_video_jobs_urls: auto_video_jobs_urls
            })


           this.get_first_process_status();

        });
    }

这是我按顺序进行ajax调用的地方

 get_first_process_status() { //this is where problem comes

        console.log("inside get_process_status")
        // console.log("current jobs are" + auto_video_jobs_urls[1])
        console.log("jobs url array length is " + auto_video_jobs_urls.length)

        auto_video_jobs_array = [];

        //initialize index counter
        let i = 0;
        let that = this;
        that.setState({loader:true})
        function next() {
            $.ajax({
                async: true,
                "crossDomain": true,
                "url": that.state.current_auto_video_jobs_urls[i],
                "method": "GET",
                "headers": {
                    Authorization: "Token " + that.props.token_Reducer.token
                },
                success: function(response, textStatus, jQxhr){
                    ++i;
                    if(i >= that.state.current_auto_video_jobs_urls.length) {
                        // run function here as its the last item in array
                        console.log("i reached last value" + i + " " + response)

                        that.setState({current_auto_video_jobs: auto_video_jobs_array, loader:false})
                        console.log("current jobs are" + that.state.current_auto_video_jobs[0])

                    } else {
                        // do the next ajax call                       
                        auto_video_jobs_array.push(response)
                        next();
                    }
                }
            });
        }


        //start the first one
        next();
    }

当我在10秒的间隔后第二次运行get_first_process_status时,错误就会消失并且媒体文件可见。这意味着ajax以正确的方式执行。只是状态current_auto_video_jobs没有以某种方式第一次映射。

它应该也是第一次工作。我无法看到任何错误原因"无法阅读财产' map'未定义"在最后一次ajax调用结束时,状态被设置。

这是我的地图功能

{this.state.current_auto_video_jobs[i].map((item, i) => {
                                                                    let w;
                                                                    if (item.eta <= 1) {
                                                                        w = item.eta
                                                                    }
                                                                    else
                                                                        w = 0;
                                                                    let s = {
                                                                        width: ((w) * 100) + "%",
                                                                    };
                                                                    return <a href="#" className="btn">
                                                                        <div className="prog-medbtn" style={s}></div>
                                                                        {item.job_type}</a>
                                                                }
                                                            )}

我该如何解决这个问题?我尝试了一切。

另外:当我使用async:false执行ajax调用时,错误就没有了。

1 个答案:

答案 0 :(得分:0)

这可能不是最佳做法,但我有时会通过以下方式防止错误:

(this.state.current_auto_video_jobs[i] || []).map

因此,如果该项目尚不存在,而不是尝试在map上调用undefined,而是在空数组上调用它。