Question: I am new to JavaScript and have been trying to get this working for a while now but to no success.

I have a function (task 3) that should only be executed after the functions before it finish. The functions before it (task 1 and 2) have more functions in them that fetch data from other sources and the time it takes for them is unknown. A wait function wouldn't really work because the time for task 1 and 2 could be very fast or very slow. I have tried doing an async/await setup but i must have done it wrong because it always completed task 3 before task 1 or 2. Same with a callback function which didn't actually callback it just did task 1 and 2 then never did task 3.

```
function task1(input){
   // has more functions that do other stuff

}
function task2(input){
   // has more functions that do other stuff
}
function task3(input){
   // this code should only be executed after both task 1 and 2 finish
}

function main(input1, input2, input3){
    task1(input1); // doesn't matter which task finishes first between 1 and 2
    task2(input2);
    task3(input3); // task 3 should not be executed until task 1 and 2 have completed.
}

main(input1, input2, input3);

```

If anyone could help that would be greatly appreciated.

Answer: 
You can filter the `invoices` Array, using the `result` Array as this-argument and check for any `Client` in that ([see MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter) for `Array.filter`). Note, the `filter`-callback should be a normal function (i.e. not an arrow function) to be able to use the result-Array for `thisArg`.

```js
console.log( `Id(s) not in result\n`, 
  [ {id: 90, Client: 'Bob', paid: false, total: 900}, 
    {id: 91, Client: 'Sarah', paid: false, total: 400},
    {id: 92, Client: 'Mia', paid: false, total: 200} ]
  .filter( 
    function(v) { return !this.find(n => n.Person === v.Client); }, 
    [{km: 200, hours: 20, Person: 'Sarah'}] // <= thisArg
   )
   .map(v => v.id) // <= fetch the found id's
   .join()
);
```

```css
.as-console-wrapper { top: 0; max-height: 100% !important; }
```
Using Set and flatMap makes for an expressive, efficient solution. Set consumes an array and lets you check for members in constant time. flatMap lets you filter and map at the same time, in essence.

```js
// Data
const invoices = [
  {id: 90, Client: 'Bob', paid: false, total: 900},
  {id: 91, Client: 'Sarah', paid: false, total: 400}
];
const personsArr = [{km: 200, hours: 20, Person: 'Sarah'}];

// Query
const persons = new Set(personsArr.map(r => r.Person));
const result = invoices.flatMap(i => !persons.has(i.Client) ? i.id : []);
console.log(result);
```