【问题标题】:Nodejs running function on backgroundNodejs在后台运行功能
【发布时间】:2020-08-06 00:32:35
【问题描述】:

我有节点程序,我需要在程序开头运行两个函数 稍后访问函数结果,当前每次等待每个函数都有效, 但是,为了节省时间而不是等待GetServiceGetProcess,因为我稍后需要项目中的数据 获取此数据大约需要 4 秒,我想在后台运行它,因为我不需要立即获得结果, 我如何在节点 js 中做到这一点,如果我运行 promise.all 它会等到 getServicegetProcess 然后去程序的其余部分。

一个例子

function main() {

//I want to run this both function in background to save time
let service = await GetServices();
this.process = await GetProcess();


…..//Here additional code is running 

//let say that after 30 second this code is called
 Let users = GetUser(service);

 Let users = GetAdress(this.process);
} 

我实际上正在运行 yeoman 生成器 https://yeoman.io/authoring/ https://yeoman.io/authoring/user-interactions.html

export default class myGenerator extends Generator {

//here I want run those function in background to save time as the prompt to the user takes some time (lets say user have many questions...) 
async initializing() {
    let service = await GetServices();
    this.process = await GetProcess();
}

async prompting() {
    const answers = await this.prompt([
      {
        type: "input",
        name: "name",
        message: "Your project name",
        default: this.appname // Default to current folder name
      },
      {
        type: "confirm",
        name: "list",
        choises: this.process //here I need to data from the function running in background
      }
    ]);

}

【问题讨论】:

    标签: javascript node.js multithreading async-await


    【解决方案1】:

    假设getServices() 可能需要 3 秒,getProcess() 可能需要 4 秒,所以如果您同时运行这两个函数,您将在总共 4 秒内返回两个 Promise 的返回值。

    你可以在这个进程在后台运行的时候执行代码,当promise解决时会有一个回调,你的后期函数会在这个阶段被调用。

    查看下面的简单示例;

    let service;
    let process;
    
    function main() {
    
        // Both functions will execute in background
        Promise.all([getServices(), getProcess()]).then((val) => {
    
            service = val[0];
            process = val[1];
    
            console.log(service, process);
    
            // Aafter completed this code will be called
            // let users = GetUser(service);
            // let users = GetAdress(process);
            console.log('I am called after all promises completed.')
        });
    
        // Current example.
        // let service = await GetServices();
        // this.process = await GetProcess();
    
        /* Code blocks.. */
        console.log('Code will execute without delay...')
    }
    
    function getServices() {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve("service is returned")
            }, 3000);
        });
    }
    
    function getProcess() {
        return new Promise((resolve, reject) => {
            setTimeout(() => {
                resolve("process is returned")
            }, 4000);
        });
    }
    
    main();

    【讨论】:

      【解决方案2】:

      要做你需要的人,你必须了解the event loop

      Nodejs 被设计为在单个线程中工作,这与 Go 等语言不同,但是 nodejs 在不同线程上处理进程。所以你可以使用nextTick()向主线程添加一个新事件,它将在整个块的末尾执行。

          function main() {
      
          //I want to run this both function in background to save time
          let service = await GetServices();
          this.process = await GetProcess();
      
      
          …..//Here additional code is running 
      
          //Let say that after 30 second this code is called
           Let users = GetUser(service);
      
           Let users = GetAdr(this.process);
          } 
      
      
       function someFunction(){
       // do something...
        }
       main();
       process.nextTick(someFunction());// happens after all main () processes are terminated...
      

      【讨论】:

        【解决方案3】:

        您可以启动异步操作但还没有等待它:

        function suppressUnhandledRejections(p) {
          p.catch(() => {});
          return p;
        }
        
        async function main() {
          // We have to suppress unhandled rejections on these promises. If they become
          // rejected before we await them later, we'd get a warning otherwise.
          const servicePromise = suppressUnhandledRejections(GetServices());
          this.processPromise = suppressUnhandledRejections(GetProcess());
        
          // Do other stuff
          const service = await servicePromise;
          const process = await this.processPromise;
        }
        

        还可以考虑使用Promise.all(),它返回一个完成所有传递给它的承诺的承诺。

        async function main() {
          const [ services, process, somethingElse ] = await Promise.all([
            GetServices(),
            GetProcess(),
            SomeOtherAsyncOperation(),
          ]);
        
          // Use the results.
        }
        

        【讨论】:

        • 谢谢。 1.如果我不能使用异步到主,我只能使用全部承诺吗?与 promise.all 它不会等待两个函数完成然后处理到getServices 等?
        • @JennyM (1) 你应该能够使main() 异步。是什么让你认为你做不到?只要确保你处理任何拒绝。 (2)Promise.all 返回的promise 在所有传入的promise 都被执行后才被执行。 调用 GetServices()GetProcess() 的行为正是这些操作的开始; Promise.all 只等待返回的承诺。它本身实际上无法启动任何异步操作。因此,异步操作都将同时进行。
        • 好的,让我试试看 :),顺便说一句,首选哪种方式(或者你会使用),第一种还是第二种?
        • @JennyM 这取决于//Here additional code is running 实际上是什么,我在你的问题中看不到。
        • @cdhowie - 请查看我的编辑,我想在后台运行函数并启动生成器提示,然后从提示访问提示的结果,我放了一些最小的例子来说明点
        猜你喜欢
        • 1970-01-01
        • 2021-04-14
        • 2021-02-26
        • 1970-01-01
        • 1970-01-01
        • 2011-12-12
        • 1970-01-01
        • 2013-02-24
        • 1970-01-01
        相关资源
        最近更新 更多