1
\$\begingroup\$

Here is some synchronous code:

let barsClient = [{
    id: 1,
    name: "The Shindig",
    goingTonight: []
  },
  {
    id: 2,
    name: "Steakapolis",
    goingTonight: []
  },
  {
    id: 3,
    name: "Booty Town",
    goingTonight: []
  }
];

let barsDB = [{
  id: 2,
  name: "Steakapolis",
  goingTonight: ["Joe", "Jim", "Joey"]
}];

function findById(bar) {
  return barsDB.find((dbBar) => {
    return dbBar.id === bar.id;
  });
}

// Check to see if bar is present in barsDB 
for (let bar of barsClient) {
  let result = findById(bar);
  // If bar is not in barsDB, add it
  if (!result) {
    barsDB.push(bar);
    // If it is present, update its goingTonight property
  } else {
    bar.goingTonight = result.goingTonight;
  }
}

// Both barsClient and barsDB should contain the same data, albeit not necessarily in the same order
console.log("barsClient:", barsClient);
console.log("barsDB:", barsDB);

Now, imagine that the findById function was asynchronous? It took me about six hours of Googling, reading and fiddling to finally figure this one out and I'm pretty happy with myself. I'm just wondering if my solution is in accordance with best practices. Here is the code to review:

let barsClient = [{
    id: 1,
    name: "The Shindig",
    goingTonight: []
  },
  {
    id: 2,
    name: "Steakapolis",
    goingTonight: []
  },
  {
    id: 3,
    name: "Booty Town",
    goingTonight: []
  }
];

let barsDB = [{
  id: 2,
  name: "Steakapolis",
  goingTonight: ["Joe", "Jim", "Joey"]
}];

function findById(bar) {
  return barsDB.find((dbBar) => {
    return dbBar.id === bar.id;
  });
}

function findByIdAsync(bar) {
  var promise = new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve(findById(bar));
    }, 3000);
  });
  return promise;
}

Promise.all(barsClient.map((bar, i) => {
    return findByIdAsync(bar)
      .then(function(result) {
        if (!result) {
          barsDB.push(bar);
        } else {
          bar.goingTonight = result.goingTonight;
        }
      });
  }))
  .then(() => {
    console.log("barsClient:", barsClient);
    console.log("barsDB", barsDB);
  });

\$\endgroup\$
2
\$\begingroup\$

From reading it I think it makes more sense to put:

.then(function(result) {
        if (!result) {
          barsDB.push(bar);
        } else {
          bar.goingTonight = result.goingTonight;
        }
      });

Into the promise that is actually executing that code:

function findByIdAsync(bar) {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      const result = findById(bar)
      if (result) {
        bar.goingTonight = result.goingTonight;
        resolve("Successfully updated bar")
      } else {
        barsDB.push(bar);
        resolve("Successfully added new bar")
      }
    }, 3000);
  });
}

Then you can just call the array of promises as so:

Promise.all(barsClient.map(findByIdAsync))
  .then(() => {
    console.log("barsClient:", barsClient);
    console.log("barsDB", barsDB);
  });

It seems that the concerns are more aligned this way.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.