Javascript - 一个函数首先依赖于其他函数 运行
Javascript - one function is dependent on others running first
免责声明:我主要在 Python 工作,我很确定我的问题与我对 Javascript 的异步性质的根本误解有关。如果是这样,非常感谢任何解释。
无论哪种方式,我的具体问题是使用 plotly 和 d3 从 csv 加载数据然后绘制它。这是一个示例 csv(在我的代码中称为 "fake_data.csv")
x,y,z
0.0,0.0,5.4
0.0,2.1,4.1
3.2,1.5,3.2
我有一个 index.html
像这样:
<head>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<div id="graph" style="width:100%;height:100%"></div>
<script src="scatter.js"></script>
</body>
然后我有我的 scatter.js
脚本,它调用。它以一个简单的辅助函数开始,用于解压 csv:
function unpack(rows, key) {
return rows.map(function(row)
{ return row[key]; });
}
对于绘图功能,如果我这样做就可以正常工作:
Plotly.d3.csv('fake_data.csv', function(err, rows){
var x = unpack(rows , 'x');
var y = unpack(rows , 'y');
var z = unpack(rows , 'z');
Plotly.plot('graph', [
{
type: 'scatter3d',
mode: 'lines',
x: x,
y: y,
z: z
}], {
height: 640
});
});
但我需要能够加载多个 csv,以便将所有必要的信息都添加到绘图中。所以我尝试将其包装在两个函数中,并像这样调用它们:
var x;
var y;
var z;
function getData(filename) {
Plotly.d3.csv(filename, function(err, rows){
x = unpack(rows , 'x');
y = unpack(rows , 'y');
z = unpack(rows , 'z');
});
}
function makePlot() {
console.log(x)
Plotly.plot('graph', [
{
type: 'scatter3d',
mode: 'markers',
x: x,
y: y,
z: z
}], {
height: 640
});
}
getData('fake_data.csv');
makePlot();
这什么也没有呈现。 makePlot()
里面的 console.log(x)
打印 undefined
.
但是 当我在控制台中键入 makePlot()
时(我正在使用 Chrome 开发人员工具)页面加载后,它工作了!那我做错了什么?我的猜测是 makePlot()
被称为 "before" getData()
所以 x
还没有值。但是我想不出正确的方法来告诉 Javascript 调用一个函数 然后 在它之后调用另一个函数。
在此先感谢您的任何建议。这感觉像是一个非常基本的概念,我只是在用头撞墙。
D3 使用旧式回调方法。
所以你可以做那个模型,或者用 Promise 包装。
var x;
var y;
var z;
function getData(filename, resolve, reject) {
if (!reject) reject = (err) => console.log(err);
return new Promise((resolve, reject) => {
Plotly.d3.csv(filename, function(err, rows) {
x = unpack(rows, 'x');
y = unpack(rows, 'y');
z = unpack(rows, 'z');
// if error
reject(err);
// resolve here
resolve();
});
});
}
function makePlot() {
console.log(x)
Plotly.plot('graph', [{
type: 'scatter3d',
mode: 'markers',
x: x,
y: y,
z: z
}], {
height: 640
});
}
getData('fake_data.csv', makePlot);
只是为了补充 的回答:如果您确切知道要下载哪些 csv 文件以执行 makePlot()
,您可以简单地使用 Promise.all
来确保所有文件都在之前显示密谋。
var x;
var y;
var z;
function getData(filename, resolve, reject) {
if (!reject) reject = (err) => console.log(err);
return new Promise((resolve, reject) => {
Plotly.d3.csv(filename, function(err, rows) {
x = unpack(rows, 'x');
y = unpack(rows, 'y');
z = unpack(rows, 'z');
// if error
if (err instanceof Error) {
reject(err);
} else {
// resolve here
resolve(true); // return true to check resolve status
}
});
});
}
function makePlot() {
console.log(x)
Plotly.plot('graph', [{
type: 'scatter3d',
mode: 'markers',
x: x,
y: y,
z: z
}], {
height: 640
});
}
var promise1 = getData('fake_data.csv');
var promise2 = getData('fake_data2.csv');
var promise3 = getData('fake_data3.csv');
Promise.all([
promise1,
promise2,
promise3
]).then(function(values) {
// check if all promises are resolved
if (values.every(function(value) { return value == true })) {
makePlot();
}
})
免责声明:我主要在 Python 工作,我很确定我的问题与我对 Javascript 的异步性质的根本误解有关。如果是这样,非常感谢任何解释。
无论哪种方式,我的具体问题是使用 plotly 和 d3 从 csv 加载数据然后绘制它。这是一个示例 csv(在我的代码中称为 "fake_data.csv")
x,y,z
0.0,0.0,5.4
0.0,2.1,4.1
3.2,1.5,3.2
我有一个 index.html
像这样:
<head>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
</head>
<body>
<div id="graph" style="width:100%;height:100%"></div>
<script src="scatter.js"></script>
</body>
然后我有我的 scatter.js
脚本,它调用。它以一个简单的辅助函数开始,用于解压 csv:
function unpack(rows, key) {
return rows.map(function(row)
{ return row[key]; });
}
对于绘图功能,如果我这样做就可以正常工作:
Plotly.d3.csv('fake_data.csv', function(err, rows){
var x = unpack(rows , 'x');
var y = unpack(rows , 'y');
var z = unpack(rows , 'z');
Plotly.plot('graph', [
{
type: 'scatter3d',
mode: 'lines',
x: x,
y: y,
z: z
}], {
height: 640
});
});
但我需要能够加载多个 csv,以便将所有必要的信息都添加到绘图中。所以我尝试将其包装在两个函数中,并像这样调用它们:
var x;
var y;
var z;
function getData(filename) {
Plotly.d3.csv(filename, function(err, rows){
x = unpack(rows , 'x');
y = unpack(rows , 'y');
z = unpack(rows , 'z');
});
}
function makePlot() {
console.log(x)
Plotly.plot('graph', [
{
type: 'scatter3d',
mode: 'markers',
x: x,
y: y,
z: z
}], {
height: 640
});
}
getData('fake_data.csv');
makePlot();
这什么也没有呈现。 makePlot()
里面的 console.log(x)
打印 undefined
.
但是 当我在控制台中键入 makePlot()
时(我正在使用 Chrome 开发人员工具)页面加载后,它工作了!那我做错了什么?我的猜测是 makePlot()
被称为 "before" getData()
所以 x
还没有值。但是我想不出正确的方法来告诉 Javascript 调用一个函数 然后 在它之后调用另一个函数。
在此先感谢您的任何建议。这感觉像是一个非常基本的概念,我只是在用头撞墙。
D3 使用旧式回调方法。 所以你可以做那个模型,或者用 Promise 包装。
var x;
var y;
var z;
function getData(filename, resolve, reject) {
if (!reject) reject = (err) => console.log(err);
return new Promise((resolve, reject) => {
Plotly.d3.csv(filename, function(err, rows) {
x = unpack(rows, 'x');
y = unpack(rows, 'y');
z = unpack(rows, 'z');
// if error
reject(err);
// resolve here
resolve();
});
});
}
function makePlot() {
console.log(x)
Plotly.plot('graph', [{
type: 'scatter3d',
mode: 'markers',
x: x,
y: y,
z: z
}], {
height: 640
});
}
getData('fake_data.csv', makePlot);
只是为了补充 makePlot()
,您可以简单地使用 Promise.all
来确保所有文件都在之前显示密谋。
var x;
var y;
var z;
function getData(filename, resolve, reject) {
if (!reject) reject = (err) => console.log(err);
return new Promise((resolve, reject) => {
Plotly.d3.csv(filename, function(err, rows) {
x = unpack(rows, 'x');
y = unpack(rows, 'y');
z = unpack(rows, 'z');
// if error
if (err instanceof Error) {
reject(err);
} else {
// resolve here
resolve(true); // return true to check resolve status
}
});
});
}
function makePlot() {
console.log(x)
Plotly.plot('graph', [{
type: 'scatter3d',
mode: 'markers',
x: x,
y: y,
z: z
}], {
height: 640
});
}
var promise1 = getData('fake_data.csv');
var promise2 = getData('fake_data2.csv');
var promise3 = getData('fake_data3.csv');
Promise.all([
promise1,
promise2,
promise3
]).then(function(values) {
// check if all promises are resolved
if (values.every(function(value) { return value == true })) {
makePlot();
}
})