在一个请求中逐个发送回复?

时间:2017-12-07 11:38:45

标签: javascript node.js express asynchronous

有没有办法在每次响应时发出1个请求和write?我想发出1个请求,并在内部对数据库发出10个请求,当查询响应写入html时?我怎样才能做到这一点?

我的api

routeHandlers = () => {
    let data: Array<any> = [];
    this._router.get('/api/countdetails/:uid', (req, res) => {
        let uid = req.params.uid;
        console.log(req);
        for (let i = 0; i < 10; i++) {
            data.push({
                id: 'request' + i,
                startTime: performance().toFixed(3)
            });

            let query = `SELECT ${i} AS ID, * FROM CountDetails WHERE UID='${uid}'`;
            this._db.execQuery(query, (err, row) => {
                if (err) throw err;

                for (let i = 0; i < data.length; i++) {
                    Object.keys(data[i]).forEach((val, idx) => {
                        if (val === 'id') {
                            if (data[i][val] === 'request' + row[0]['ID']) {
                                data[i].endTime = performance().toFixed(3);
                                data[i].ellapsed = (performance() - data[i]['startTime']).toFixed(3);
                                res.write('<tr><td>' + data[i]['ellapsed'] + '</td></tr>');

                            }
                        }
                    });
                }

            });

        res.header("Access-Control-Allow-Origin", "*");
        res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
        res.end();
        }

    }); 
}

和我的 html

<div>
    <input type="text" id="iterations" />
    <button type="button" id="btn">send</button>
</div>
<div>
    <table id="tbl">
        <tbody>

        </tbody>
    </table>
</div>

<script>
    var inputValue = document.getElementById('iterations');
    var btn = document.getElementById('btn');
    var array = [];

    btn.addEventListener('click', function () {
        sendRequest(function (xhttp) {
            console.log(xhttp.responseText);
        })
    });

    function sendRequest(callback) {
        var xhttp = new XMLHttpRequest();
        xhttp.onreadystatechange = function() {
            if (this.readyState == 4 && this.status == 200) {
               callback(xhttp);
            }
        };
        xhttp.open("GET", "http://localhost:3000/api/countdetails/EAACCDF4-EBC3-4B11-8654-98878BFC4B7B", true);
        xhttp.send({ times: 10});
    }
</script>

1 个答案:

答案 0 :(得分:1)

首先不要将i用于嵌套for

因此,您希望在完成所有数据库调用后调用res.end()。这可以通过多种方式完成,但我会快速给您一些代码调整。这是代码片段,后面是解释:(还读取代码中的注释

routeHandlers = () => {

    /* 1) we can use the indicator to determine when all the async requests are finished */
    let indicator = 0;
    let data = [];

    this._router.get('/api/countdetails/:uid', (req, res) => {

        /* 2) always set the indicator to 0 on a new request */
        indicator = 0;
        let uid = req.params.uid;

        for (let i = 0; i < 10; i++) {
            data.push({
                id: 'request' + i,
                startTime: performance().toFixed(3)
            });

            let query = `SELECT ${i} AS ID, * FROM CountDetails WHERE UID='${uid}'`;
            this._db.execQuery(query, (err, row) => {
                if (err)
                    throw err;

                for (let j = 0; j < data.length; j++) {
                    Object.keys(data[j]).forEach((val, idx) => {
                        if (val === 'id') {
                            if (data[j][val] === 'request' + row[0]['ID']) {
                                data[j].endTime = performance().toFixed(3);
                                data[j].ellapsed = (performance() - data[j]['startTime']).toFixed(3);
                                res.write('<tr><td>' + data[j]['ellapsed'] + '</td></tr>');
                            }
                        }
                    });
                }

                /* 3) here check if indicator is 10 and if yes then all the database calls should be finished */
                indicator++;
                if (indicator === 10) {
                    res.header("Access-Control-Allow-Origin", "*");
                    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
                    res.end();
                }
            });
        }
    });
}

简而言之,我将使用整数变量作为指示完成了多少数据库调用,一旦达到数字10,我认为所有数据都已完成并结束响应。

1)声明indicator变量,这将有助于我们确定作业何时就绪;

2)在每个即将到来的请求中重置指示符(您可能还认为重置 data

3)数据库调用完成后,递增indicator并检查其值 - &gt;如果是10那么我们就完成了并结束了回复。

就是这样,简短而简单。如果有什么不清楚,请告诉我。