我有一个调用两个模块的主菜单功能。第一个获取数据并将其写入文件。第二个打开该文件并在其上运行测试。我一生无法获得第二个功能,直到第一个功能完成并创建了必要的文件。 Err始终是文件不存在。这两个文件分别按预期工作,并在命令行中单独运行。简而言之,我正在尝试:
const test1 = require('./daytrade2.js');
const getstock = require('./yahoodatapuller2.js');
const process = require('process');
var args = process.argv;
let domefirst=function(){
return new Promise(function(resolve,reject){
var promisefinished=0;
promisefinished= getstock.main(args[2])
if(promisefinished)
{
resolve(1)
}
})}
domefirst().then((result)=>{if(result)
{test1.main(args[2],args[3])}
}).catch((err)=>{console.log(err)})
另外,运行以下命令会产生相同的错误
domefirst().then(()=>{test1.main(args[2],args[3])
}).catch((err)=>{console.log(err)})
进一步,这就是库存
exports.main= function(stocksym){
//var stocksym='AAPL';
const https= require('https');
var lockup=[];
fs =require('fs')
var open=[];
var close=[];
var high=[];
var low=[];
var dd=[];
var mm=[];
var yy=[];
var wkday=[];
var timestamps=[];
var volume=[];
modules = [
'assetProfile',//0
'summaryProfile',
'summaryDetail',//2
'esgScores',
'price',//4
'incomeStatementHistory',//6
'incomeStatementHistoryQuarterly',
'balanceSheetHistory',//8
'balanceSheetHistoryQuarterly',
'cashflowStatementHistory',
'cashflowStatementHistoryQuarterly',
'defaultKeyStatistics',
'financialData',
'calendarEvents',
'secFilings',
'recommendationTrend',
'upgradeDowngradeHistory',
'institutionOwnership',
'fundOwnership',
'majorDirectHolders',
'majorHoldersBreakdown',
'insiderTransactions',
'insiderHolders',
'netSharePurchaseActivity',
'earnings',
'earningsHistory',
'earningsTrend',
'industryTrend',
'indexTrend',
'sectorTrend' ]
function spacer(data){
data=JSON.stringify(data)
for (i=0; i<data.length;i++)
{
if (data[i]==',')
{
data.splice(i,0,'\n')
}
}
return JSON.parse(data);
}
function rounder(num){
num=Math.round((num + Number.EPSILON) * 100) / 100;
return num;
}
var calltime=0;
var before='';
var after='';
var fileout= function(summary){
return new Promise(function(resolve,reject){
var promisedone= false;
calltime+=1;
var json= JSON.stringify(summary)
var fname=stocksym+'.json'
switch(calltime){
case 1:
before= '{"dd":';
after= ',\n';
break;
case 2:
before= '"mm":';
after= ',\n';
break;
case 3:
before= '"yy":';
after=',\n';
break;
case 4:
before= '"wkday":';
after=',\n';
break;
case 5:
before= '"open":';
after=',\n';
break;
case 6:
before= '"close":';
after=',\n';
break;
case 7:
before= '"high":';
after=',\n';
break;
case 8:
before= '"low":';
after=',\n';
break;
case 9:
before= '"volume":';
after='}\n';
calltime=0;
break;
default:
console.log('error switch line 114');
}
fs.appendFile(fname,before + json+ after, function(err) {
if (err) throw err;
// if no error
console.log("Data is appended to file successfully.")
promisedone= true;
if(promisedone)
{
promisedone=false;
resolve();
}
})
})
}
var p1='1595203200';//startdate unix (usually 0)
var p2='1596039048';//enddate
var int='1d'; // "1d","5d","1mo","3mo","6mo","1y","2y","5y","10y","ytd","max"
var url='https://query1.finance.yahoo.com/v8/finance/chart/'+stocksym+'?symbol='+stocksym+'&period1='+p1+'&period2='+p2+'&interval='+int;
var furl=url;
https.get( furl,
res => {
var body= '';
res.on('data',data=>{
body+=(data);
})
res.on('end',function(){
body=JSON.stringify(body);
body=JSON.parse(body)
body=JSON.parse(body)
var d= new Date();
for(i=0;i<body.chart.result[0].timestamp.length; i++)
{
timestamps.push(body.chart.result[0].timestamp[i] *1000)
d= new Date(timestamps[i])
dd.push(d.getDate());
mm.push(d.getMonth());
yy.push(d.getFullYear());
wkday.push(d.getDay());
open.push(rounder(body.chart.result[0].indicators.quote[0].open[i]));
close.push(rounder(body.chart.result[0].indicators.quote[0].close[i]));
high.push(rounder(body.chart.result[0].indicators.quote[0].high[i]));
low.push(rounder(body.chart.result[0].indicators.quote[0].low[i]));
volume.push(body.chart.result[0].indicators.quote[0].volume[i]);
}
fileout(dd).then(()=>{fileout(mm);
}).then(()=>{ fileout(yy);
}).then(()=>{ fileout(wkday);
}).then(()=>{ fileout(open);
}).then(()=>{ fileout(close);
}).then(()=>{ fileout(high);
}).then(()=>{ fileout(low);
}).then(()=>{ fileout(volume);
}).catch((err)=>{console.log(err)})
//console.log(dd + '\n'+mm+'\n'+ yy+ '\n'+wkday+ '\n'+ open + '\n'+ close + '\n'+ high + '\n'+ low + '\n'+ volume)
})
})
return 1;
}
答案 0 :(得分:0)
getstock()
在完成时似乎没有以任何方式回传,因此调用方无法知道何时完成。因此,您将需要对其进行修复,以便它返回完成后可以解决的承诺。您也没有办法传达回错误。
好吧,我该如何从导出的函数返回一个承诺?
它是否被导出都没有关系-它只是一个函数。您可以在fileout()
中将承诺内置到getstock.main()
中并返回它,方法与之相同。另外,您实际上不应该混合使用promise和普通回调。进行所有尚未返回promise的低级异步操作,并制作一个返回promise的包装,然后仅对控制流使用promise逻辑。
其他一些提示:
let
和const
。var
。fs.promises
界面获取已经使用诺言的fs
模块功能。got()
的方式代替https.get()
进行基于承诺的https提取。promisedone
变量。它似乎没有做任何有用的事情,并使事情看起来比实际情况更加复杂。这里是fileout()
的示例重写,它使用fs.promises.appendFile()
,使用表查找而不是巨型switch()
,并将所有内容切换到const
和let
:
function fileout(summary) {
const prefixes = [
'{"dd":', '"mm":', '"yy":', '"wkday":', '"open":',
'"close":', '"high":', '"low":', '"volume":',
];
calltime += 1;
const json = JSON.stringify(summary);
const fname = stocksym + '.json';
const before = prefixes[calltime - 1];
let after = ',\n';
if (calltime === prefixes.length) {
after = '}\n';
calltime = 0;
}
return fs.promises.appendFile(fname, before + json + after);
}
您可能还应该更改calltime
变量的工作方式,因为这是副作用编程,通常不是一个好主意。也许您应该只将该变量传递到fileout()
中,并让调用方对其进行递增和控制。
相同的概念可以应用于较大的功能。
这里尝试进行更大的重写以简化很多操作:
const fs = require('fs');
const got = require('got');
exports.main = async function(stocksym) {
// create initial object that we want to write JSON version of to the file
const stockData = {
dd: [],
mm: [],
yy: [],
wkday: [],
open: [],
close: [],
high: [],
low: [],
volume: []
};
function rounder(num){
return Math.round((num + Number.EPSILON) * 100) / 100;
}
// get the stock data
const p1 = '1595203200'; //startdate unix (usually 0)
const p2 = '1596039048'; //enddate
const int = '1d'; // "1d","5d","1mo","3mo","6mo","1y","2y","5y","10y","ytd","max"
const url = `https://query1.finance.yahoo.com/v8/finance/chart/${stocksym}?symbol=${stocksym}&period1=${p1}&period2=${p2}&interval=${int}`;
console.log(url);
const {chart} = await got(url).json();
const timestamps = [];
for (let i = 0; i < chart.result[0].timestamp.length; i++) {
timestamps.push(chart.result[0].timestamp[i] * 1000);
const d = new Date(timestamps[i])
stockData.dd.push(d.getDate());
stockData.mm.push(d.getMonth());
stockData.yy.push(d.getFullYear());
stockData.wkday.push(d.getDay());
stockData.open.push(rounder(chart.result[0].indicators.quote[0].open[i]));
stockData.close.push(rounder(chart.result[0].indicators.quote[0].close[i]));
stockData.high.push(rounder(chart.result[0].indicators.quote[0].high[i]));
stockData.low.push(rounder(chart.result[0].indicators.quote[0].low[i]));
stockData.volume.push(chart.result[0].indicators.quote[0].volume[i]);
}
const fname = stocksym + '.json';
return fs.promises.writeFile(fname, JSON.stringify(stockData));
}
这个getstock.main()
的新版本返回一个承诺,该承诺在完成后会解决/拒绝。然后,调用者可以使用该承诺,通过对该承诺使用await
或.then()
和.catch()
来知道何时完成所有操作。