NPM run parallel task, but wait until resource is

2019-04-09 08:34发布

问题:

In npm, how can I run two or more parallel tasks, but waiting for the resource that the first task will create to be available to the second task to use it, and so forth?

example (conceptual):

npm run task1 & waitfor task1 then task2 & waitFor task3 then task4 ...

any ideas?

EDIT

As an example: Lets say that my first task is starting a webserver, and my second task is consuming data from that web-server every time an event happens. Another example: My first task could be starting webdriver-manager, my second task, starting a webserver, and my third task, run e2e tests everty time my files are changed. So, I need all those tasks to keep running concurrently, but they need to be initialized in an specific order and time.

回答1:

You can try concurrently with wait-on package in order to manage conccurent/sequential scripts and outputs. wait-on sequential launches support head response status, tcp listening, ...

For example :

"scripts": {
    "start": "concurrently -k -n \"DB,API,WEB\" -c \"blue,magenta,yellow\" \"npm run start-db\" \"npm run start-api\" \"npm run start-web\"",
    "start-db": "myDbServerCmd",
    "start-api": "wait-on tcp:27017 && myApiServerCmd",
    "start-web": "myFrontServerCmd",
}

Thanks dchambers for the idea (source).



回答2:

I'm not sure I fully understand your requirement, so I'll provide a few possible solutions.

It may be that you are wanting to run tasks sequentially (the first solution below), however in your post you mention parallel.


1. Running Tasks sequentially

npm-scripts supports the && operator which is typically used in bash shells. The && operator, used in npm-scripts, does however work successfully cross-platform.

Pseudo example using the && operator for chaining tasks:

"scripts": {
    "foo": "npm run task1 && npm run task2 && npm run task3"
},

Running $ npm run foo via your CLI using the example above...

  1. Initially runs task1.
  2. When task1 has successfully completed (i.e. task1 exits with a status of zero) then task2 will be run.
  3. When task2 has successfully completed then task3 will be run.

If the left side of && operator fails for whatever reason, (i.e. it exits with non-zero code/status), the subsequent task(s) on the right side will fail to run. For example; if task1 fails then task2 and task3 will not run.


2. Running Tasks simultaneously

npm-scripts also supports the single & operator cross-platform for running tasks simultaneously.

Pseudo example using the & operator:

"scripts": {
    "foo": "npm run task1 & npm run task2 & npm run task3"
},

In this example the main difference between the double && and the single & operator is that if the left side of the single & fails, then the right side runs regardless. For example; if task1 fails then task2 still runs.


3. Running Tasks in parallel.

To run tasks in parallel I recommend you utilize parallelshell:

$ npm i -D parallelshell

Pseudo example using parallelshell:

"scripts": {
    "foo": "parallelshell \"npm run task1\" \"npm run task2\" \"npm run task3\""
},

This example initially seems very similar to using the single & operator shown in the previous section, however it offers additional benefits as listed in the documentation. The main benefit (IMO) being:

If command1 or command2 exit with non-zero exit code, then this will not effect the outcome of your shell (i.e. they can fail and npm/bash/whatever will ignore it). parallelshell will not ignore it, and will exit with the first non-zero exit code.


4. Running Tasks in parallel and sequentially.

Lets say you want to run task1 and task2 in parallel/simultaneously and then run task3 only when both task1 and task2 have successfully completed.

To achieve this you can utilize both parallelshell and the built-in && operator.

Pseudo example using parallelshell and the && operator for chaining tasks:

"scripts": {
    "foo": "parallelshell \"npm run task1\" \"npm run task2\" && npm run task3"
},

EDIT

A solution based on the following OP's update/edit:

Another example: My first task could be starting webdriver-manager, my second task, starting a webserver, and my third task, run e2e tests everty time my files are changed. So, I need all those tasks to keep running concurrently, but they need to be initialized in an specific order and time.

5. Running Tasks concurrently.

concurrently can be utilized to run tasks concurrently:

$ npm i -D concurrently

Pseudo example using concurrently:

"scripts": {
    "foo":  "concurrently \"npm run task1\" \"npm run task2\" \"npm run task3\""
},

This example will keep all tasks (1,2, and 3) running concurrently, and they'll start in the order specified. I don't know enough detail of the tools mentioned in your example use case, however all examples provided in this post can be combined as necessary to meet your exact requirement.

concurrently also has several useful options too.