No need to wrap everything in Promise

    Original article


    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.

    Also popular now: