Javascript 只有在另一个脚本完成后才能运行脚本的方法有哪些?

Javascript 只有在另一个脚本完成后才能运行脚本的方法有哪些?,javascript,node.js,asynchronous,promise,callback,Javascript,Node.js,Asynchronous,Promise,Callback,让我们假设这是我的代码,只是我写的一个示例来展示我的想法 var extract = require("./postextract.js"); var rescore = require("./standardaddress.js"); RunFunc(); function RunFunc() { extract.Start(); console.log("Extraction complete"); rescore.Start(); console.log

让我们假设这是我的代码,只是我写的一个示例来展示我的想法

var extract = require("./postextract.js");
var rescore = require("./standardaddress.js");

RunFunc();

function RunFunc() {
    extract.Start();
    console.log("Extraction complete");
    rescore.Start();
    console.log("Scoring complete");
}
我不想让rescore.Start在整个extract.Start完成之前运行。这两个脚本都包含一个蜘蛛网函数,因此将回调直接放入Start函数似乎不可行,因为最终函数不会返回它,而且我在理解如何使用承诺方面遇到了很多困难。我有什么方法可以让它工作

这些是提取的脚本。Start以开始和结束。OpenWriter是通过多个其他函数和流来实现的,实际的fileWrite.write位于另一个脚本中,该脚本附于此,尽管不需要检测运行的结束。目前,fileWrite.on'finish'是我希望脚本被确定为完成的地方

module.exports = {
  Start: function CodeFileRead() {
    //this.country = countryIn;
    //Read stream of thate address components
    fs.createReadStream("Reference\\" + postValid.country + " ADDRESS REF DATA.csv")
      //Change separator based on file
      .pipe(csv({escape: null, headers: false, separator: delim}))
      //Indicate start of reading
      .on('resume', (data) => console.log("Reading complete postal code file..."))
      //Processes lines of data into storage array for comparison
      .on('data', (data) => {
        postValid.addProper[data[1]] = JSON.stringify(Object.values(data)).replace(/"/g, '').split(',').join('*');
        })
      //End of reading file
      .on('end', () => {
        postValid.complete = true;
        console.log("Done reading");
        //Launch main script, delayed to here in order to not read ahead of this stream
        ThisFunc();
      });
  },

  extractDone
}

function OpenWriter() {
    //File stream for writing the processed chunks into a new file
    fileWrite = fs.createWriteStream("Processed\\" + fileName.split('.')[0] + "_processed." + fileName.split('.')[1]);
    fileWrite.on('open', () => console.log("File write is open"));
    fileWrite.on('finish', () => {
      console.log("File write is closed");
    });
}
编辑:我不想简单地将下一个脚本添加到上一个脚本的末尾,并放弃主文件,因为我不知道它需要多长时间,并且它的设计应该能够在我们的开发周期之后使用其他脚本。我不能只使用现有的软件包,因为公司的审批时间长达两周,我更需要它


双重编辑:这是我所有的代码,每个脚本和函数都是我编写的,因此我可以让被调用的脚本执行所需的操作

没有通用的方法来确定函数调用的所有操作何时完成

它可能会接受回调。它可能会回报一个承诺。它可能不提供任何类型的方法来确定何时完成。它可能有副作用,您可以通过轮询来监控


您需要阅读特定函数的文档和/或源代码。

没有通用的方法来确定函数调用的所有操作何时完成

它可能会接受回调。它可能会回报一个承诺。它可能不提供任何类型的方法来确定何时完成。它可能有副作用,您可以通过轮询来监控


您需要阅读该特定函数的文档和/或源代码。

使用异步/等待承诺,例如:

var extract=require./postextract.js; var rescore=require./standardaddress.js; RunFunc; 异步函数提取\u启动{ 试一试{ 提取,开始 } 抓住{ 控制台日志 } } 异步函数rescore\u start{ 试一试{ 重新开始 } 抓住{ 控制台日志 } } 异步函数RunFunc{ 等待提取开始; 控制台。日志提取完成; 等待重新开始; 控制台。完成日志评分;
} 使用异步/等待承诺,例如:

var extract=require./postextract.js; var rescore=require./standardaddress.js; RunFunc; 异步函数提取\u启动{ 试一试{ 提取,开始 } 抓住{ 控制台日志 } } 异步函数rescore\u start{ 试一试{ 重新开始 } 抓住{ 控制台日志 } } 异步函数RunFunc{ 等待提取开始; 控制台。日志提取完成; 等待重新开始; 控制台。完成日志评分;
} 您可以将函数包装为Promise并返回它

module.exports = {
  Start: function CodeFileRead() {
    return new Promise((resolve, reject) => {
      fs.createReadStream(
        'Reference\\' + postValid.country + ' ADDRESS REF DATA.csv'
      )
      // .......some code...
      .on('end', () => {
        postValid.complete = true;
        console.log('Done reading');
        resolve('success');
      });
    });
  }
};
然后像这样运行RunFunc:

async function RunFunc() {
  await extract.Start();
  console.log("Extraction complete");
  await rescore.Start();
  console.log("Scoring complete");
}

//or IIFE
RunFunc().then(()=>{
  console.log("All Complete");
})
注意:当发生错误时,您还可以/应该通过拒绝某些错误来处理错误

了解基金后编辑:

创建新的事件发射器可能是最简单的解决方案: eventEmitter.js

const EventEmitter = require('events').EventEmitter
module.exports = new EventEmitter()

然后像以前一样运行RunFunc。

您可以用Promise包装函数并返回它

module.exports = {
  Start: function CodeFileRead() {
    return new Promise((resolve, reject) => {
      fs.createReadStream(
        'Reference\\' + postValid.country + ' ADDRESS REF DATA.csv'
      )
      // .......some code...
      .on('end', () => {
        postValid.complete = true;
        console.log('Done reading');
        resolve('success');
      });
    });
  }
};
然后像这样运行RunFunc:

async function RunFunc() {
  await extract.Start();
  console.log("Extraction complete");
  await rescore.Start();
  console.log("Scoring complete");
}

//or IIFE
RunFunc().then(()=>{
  console.log("All Complete");
})
注意:当发生错误时,您还可以/应该通过拒绝某些错误来处理错误

了解基金后编辑:

创建新的事件发射器可能是最简单的解决方案: eventEmitter.js

const EventEmitter = require('events').EventEmitter
module.exports = new EventEmitter()

然后像以前一样运行RunFunc。

执行提取。开始返回承诺?我如何让它这样做?我写了它们,所以无论我想要它返回什么,我只是不确定你必须在哪里或如何发布一个简单的最小完整的可验证的extract.Start和rescore.Start代码示例;将其添加到帖子中,它显示了第一个和最后一个脚本,两个脚本的功能相同,以读流开始,以写流结束。开始返回承诺?我如何让它这样做?我写了它们,所以无论我想要它返回什么,我只是不确定你必须在哪里或如何发布一个简单的最小完整的可验证的extract.Start和rescore.Start代码示例;将其添加到帖子中,它显示了第一个和最后一个脚本,两个脚本的功能相同,从读流开始,以写流结束。它们是我的功能,我编写了整个代码,因此我可以让它们返回或执行其他操作needed@TheBasementNerd-我们不知道他们做什么。在这个回答中,我提出了三件事,可以用来确定异步代码何时完成,尽管轮询的副作用很糟糕。选择其中一个并生成函数
我不知道除了回调之外,我该如何把它们放进去,但由于它调用脚本中的一个函数,脚本以另一个函数结束,没有通过每个函数传递回调,我认为这是不可行的。或者听起来可能是这样的吗?它们是我的函数,我写了整个代码,所以我可以让它们返回或者做我想做的事情needed@TheBasementNerd-我们不知道他们做什么。在这个回答中,我提出了三件事,可以用来确定异步代码何时完成,尽管轮询的副作用很糟糕。我不知道除了回调之外,我该如何把它们放进这个函数中,但是由于它调用脚本中的一个函数,脚本以另一个函数结束,没有通过每个函数传递回调,我认为这是不可行的。或者听起来可能是这样的吗?这最终只是运行extract。启动然后程序完成,这似乎是我尝试执行承诺系统的大多数时候的问题,还是我需要在extract和rescore脚本中添加一些内容?这最终只是运行extract。启动然后程序完成,这似乎是大多数时候我尝试使用promise系统的问题,或者我需要在extract和rescore脚本中添加一些内容吗?这最终会将它们一起运行,而不是等待整个脚本完成。因此ThisFunc也是异步函数?我认为这是一个伪函数,它调用了该脚本函数链中的下一个函数。这条链最终以OpenWriter被调用而告终。这不是异步的,只是因为我们需要在开始处理所有数据之前将整个文件加载到内存中。这对我的家庭自动化系统也会有帮助,因为我需要一种方法来检测色调灯光何时发生变化,所以使用事件发射器是一种很好的方法,最终将它们一起运行,而不是等待整个脚本完成。那么ThisFunc也是异步函数吗?我认为这是一个伪函数,它调用了该脚本函数链中的下一个函数。这条链最终以OpenWriter被调用而告终。这不是异步的,只是因为我们需要在开始处理所有数据之前将整个文件加载到内存中。这对我的家庭自动化系统也会有帮助,因为我需要一种方法来检测色调灯光何时改变,所以使用事件发射器是天赐良机