【问题标题】:Pass Node.js array from endpoint to Javascript function将 Node.js 数组从端点传递到 Javascript 函数
【发布时间】:2019-10-19 15:07:23
【问题描述】:

我有一个 html 图表,它将显示来自 javascript 函数“window.testDataArray”的数组。我想用来自服务器端点的数组数据替换示例数组。我不确定我需要做什么才能实现这一目标。

客户端


window.testDataArray = function(){

        return [6.5,5.2,3.4,5.8] //sample array
    };

更新的客户端(不工作)我不确定这里的语法是否正确。非常欢迎任何帮助。我对 javascript 和 node.js 很陌生。

window.testDataArray = async function(){
        //      return [1,2,3,4,5,6,7,8,9,9,8,7,4,5,6,1,2,3] 
        try{
        return await fetch('http://localhost:3000/array').then(function (data) { 
            return data 
        }).catch(function(error){return 'testDataArray' + (error)
    });

        }
        catch(error){'Error testDataArray' + error}
    };

服务器端


const express = require('express');
const app = express();

app.get('/array', (req, res) => {
    test()
    async function test (){

    res.send(await local_db.get_data('heights'));//returns array e.g.[5.1,4.3,2.1,5.8] 
    }
    //await local_db.disconnect();
})


const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Listening on port ${port}...`));

//console.log("Server running at http://127.0.0.1:3000/ or http://localhost:3000/");

'window.testDataArray' 在 utlis.js 中并从'Line Chart.html' 调用。 window.testDataArray 无法从 node.js 服务器端点http://localhost:3000/array获取数组

对以下答案的回复(无法在本地重现答案我错过了什么?)

感谢 Emissary 的解释,您的代码就像一个魅力,但我无法让它与本地服务器一起使用。我不打算将此上传到网络上。浏览器对 runkit 端点的响应是 'Cannot GET /' 。但是当我导航到'http://localhost:3000/array' 时,我得到了[0,10,5,2,20,30,45]。请在下面查看您的代码。我已将您的 runkit 端点替换为本地端点。

<!DOCTYPE html>
<!-- saved from url=(0061)https://www.chartjs.org/samples/latest/charts/line/basic.html -->
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    <title>Line Chart</title>
    <script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0"></script>
    <canvas id="myChart"></canvas>
    <style>

@keyframes chartjs-render-animation{from{opacity:.99}to{opacity:1}}.chartjs-render-monitor{animation:chartjs-render-animation 1ms}.chartjs-size-monitor,.chartjs-size-monitor-expand,.chartjs-size-monitor-shrink{position:absolute;direction:ltr;left:0;top:0;right:0;bottom:0;overflow:hidden;pointer-events:none;visibility:hidden;z-index:-1}.chartjs-size-monitor-expand>div{position:absolute;width:1000000px;height:1000000px;left:0;top:0}.chartjs-size-monitor-shrink>div{position:absolute;width:200%;height:200%;left:0;top:0}</style></head>

<body>
    <script>

        const chart = new Chart(
    document.getElementById('myChart').getContext('2d'), 
    { 
        type: 'line',
        // ... 
    }
)

//const API_HOST = 'https://so-58465005-mqksg0z5tsf8.runkit.sh'
const API_HOST = 'http://localhost:3000'

fetch(`${API_HOST}/array`)
    .then(response => response.json())
    .then(data => { 
        chart.config.data.labels = Array.from(Array(data.length)).map((_, i) => i + 1)
        chart.config.data.datasets.push({ label: 'my data', data })
        chart.update()
    })

    </script>
</body></html>

请在下面找到服务器端代码。我已将 '@runkit/runkit/express-endpoint/1.0.0' 替换为 'express'。我一定在这里遗漏了一些基本的东西吗?再次感谢您迄今为止的帮助。

const express = require("express")
const cors = require('cors')

const app = express()

app.use(cors())

app.get("/array", (req, res) => {
    const data = [0, 10, 5, 2, 20, 30, 45]
    res.send(JSON.stringify(data))
    res.end();
})


const port = process.env.PORT || 3000;
app.listen(port, () => console.log(`Listening on port ${port}...`));
``

【问题讨论】:

  • fetch('http://localhost:3000/array').then(() =&gt; { /* do something */ }) - MDN
  • 感谢您的信息,我没有从我的函数中获得价值,我做错了什么吗? window.testDataArray = function(){ return fetch('localhost:3000/array').then((data) => {return data }) };
  • 感谢 Emissary 的链接,我已经修改了上面的代码,但仍然无法为我的 javascript 函数获取数组。有什么想法吗?
  • 问题是您不能同步处理异步调用 - async / await 通常是语法糖,允许您以命令方式编写代码,但仍然是 Promise 下的链引擎盖。无论在您的代码中使用testDataArray(),都需要以不期望立即产生结果的方式进行重组。您能否为MCVE 提供足够的客户端代码。

标签: javascript arrays node.js endpoint


【解决方案1】:

您的项目存在一些问题,我已经复制了您的 server on RunKit - 请注意两个重要组成部分:

  • 如果不在服务器端序列化它们并在客户端反序列化它们,就无法返回复合对象类型 - HTTP 数据以纯文本形式传输 - 这通常通过 JSON 完成。
  • 目前尚不清楚您从何处提供.html 文件,但看起来您可能会遇到跨域错误 - 我包含了处理此问题的中间件further reading into CORS available here

为了解决问题中描述的问题,您目前正尝试在请求响应之前将数据静态应用于配置。而是尝试对fetch 返回的承诺中的数据做出反应。

暂时忘记async / await,这可以通过将回调函数传递给.then 来实现 - 类似于您在附加示例中其他地方已经响应按钮单击事件的方式。

const chart = new Chart(
    document.getElementById('myChart').getContext('2d'), 
    { 
        type: 'line',
        // ... 
    }
)

const API_HOST = 'https://so-58465005-mqksg0z5tsf8.runkit.sh'

fetch(`${API_HOST}/array`)
    .then(response => response.json())
    .then(data => { 
        chart.config.data.labels = Array.from(Array(data.length)).map((_, i) => i + 1)
        chart.config.data.datasets.push({ label: 'my data', data })
        chart.update()
    })
<script src="https://cdn.jsdelivr.net/npm/chart.js@2.8.0"></script>
<canvas id="myChart"></canvas>

【讨论】:

  • 这在您的 runkit 端点上效果很好,但我无法在本地重现它。我究竟做错了什么?请参阅上面的修改后的帖子。非常感谢。
  • exports 是 RunKit API 的一部分,请尝试将其从 const app = express() 中删除。您现在还在编辑后的代码中请求http://localhost:3000/array/array
  • 谢谢!!现在可以了,我已经更新了上面的代码以删除我的错字。
猜你喜欢
  • 2020-07-10
  • 1970-01-01
  • 1970-01-01
  • 2016-04-08
  • 2023-01-26
  • 1970-01-01
  • 1970-01-01
  • 2012-02-11
  • 2012-06-18
相关资源
最近更新 更多