No need to wrap everything in Promise
Imagine that we are developing a function isPi:
function isPi(x) {
  return x === 3.14
}And then someone says: “We don’t want to know where the data comes from (database, network, etc.), so let's wrap our code in Promise”:
function isPi(px) {
  return px.then(x =>
    return x === 3.14
  })
}And we will call the function like this:
const px = grabXfromDb()
isPi(px)- Cool, yeah? - Not
The problem is that the statement: “We wrap the code in Promise so that asynchronous or synchronous code is not steamed” is not true. We do not wrap the code, but Promise is "something" that can:
- either "resolve" with the value
- either "fail" with an error
sometime in the future:
px.then(x =>
  // в этом месте x содержит уже известное "синхронное" значение
  isPi(x)
)So we can remove the redundant code:
function isPi(x) {
  return x === 3.14
}
const px = grabXfromDb()
px.then(isPi)You may ask: okay, the initial code is a little redundant, what's wrong with that? The problem arises when we try to add an error return - it is very easy to end with something like:
function isPi(px) {
  return px.then(x =>
    return x === 3.14
  })
  .catch(fuction(e) {
    assert(e instanceof SomeDBError)
    // какой-нибудь код на случай ошибки базы данных
  })
}This is bad because now our function knows through errors too much about the place where we got Promise. The correct way to rewrite this code is as follows:
function isPi(x) {
  return x === 3.14
}
grabXfromDb()
  .catch(fuction(e) {
    assert(e instanceof SomeDBError)
    // some code here 
  })
.then(isPi)A few simple rules:
- try to handle errors as close as possible to their source
- clearly separate asynchronous operations from synchronous ones in the code. Otherwise, you will most likely end up with very “linked” code.