Why are callbacks more “tightly coupled” than promises?

前端 未结 5 1069
Happy的楠姐
Happy的楠姐 2021-01-30 06:51

Can you explain me the following phrase (taken from an answer to Stack Overflow question What are the differences between Deferred, Promise and Future in Javascript?)?

W

相关标签:
5条回答
  • 2021-01-30 07:34

    A promise is an object that represents the result of an asynchronous operation, and because of that you can pass it around, and that gives you more flexibility.

    If you use a callback, at the time of the invocation of the asynchronous operation you have to specify how it will be handled, hence the coupling. With promises you can specify how it will be handled later.

    Here's an example, imagine you want to load some data via ajax and while doing that you want to display a loading page.

    With callbacks:

    void loadData = function(){
      showLoadingScreen();
      $.ajax("http://someurl.com", {
        complete: function(data){
          hideLoadingScreen();
          //do something with the data
        }
      });
    };
    

    The callback that handles the data coming back has to call hideLoadingScreen.

    With promises you can rewrite the snippet above so that it becomes more readable and you don't have to put the hideLoadingScreen in the complete callback.

    With promises

    var getData = function(){
      showLoadingScreen();
      return $.ajax("http://someurl.com").promise().always(hideLoadingScreen);
    };
    
    var loadData = function(){
      var gettingData = getData();
      gettingData.done(doSomethingWithTheData);
    }
    
    var doSomethingWithTheData = function(data){
     //do something with data
    };
    

    UPDATE: I've written a blog post that provides extra examples and provides a clear description of what is a promise and how its use can be compared to using callbacks.

    0 讨论(0)
  • 2021-01-30 07:39

    The coupling is looser with promises because the operation doesn't have to "know" how it continues, it only has to know when it is ready.

    When you use callbacks, the asynchronous operation actually has a reference to its continuation, which is not its business.

    With promises, you can easily create an expression over an asynchronous operation before you even decide how it's going to resolve.

    So promises help separate the concerns of chaining events versus doing the actual work.

    0 讨论(0)
  • 2021-01-30 07:39

    They aren't, this is just a rationalization that people who are completely missing the point of promises use to justify writing a lot more code than they would write using callbacks. Given that there is obviously no benefit in doing this, you can at least always tell yourself that the code is less coupled or something.

    See what are promises and why should I use them for actual concrete benefits.

    0 讨论(0)
  • 2021-01-30 07:45

    Promises reify the concept of delayed response to something. They make asynchronous computation a first-class citizen as you can pass it around. They allow you to define structure if you want - monadic structure that is - upon which you can build higher order combinators that greatly simplify the code.

    For example you can have a function that takes an array of promises and returns a promise of an array(usually this is called sequence). This is very hard to do or even impossible with callbacks. And such combinators don't just make code easier to write, they make it much easier to read.

    Now consider it the other way around to answer your question. Callbacks are an ad-hoc solution where promises allow for clearer structure and re-usability.

    0 讨论(0)
  • 2021-01-30 07:46

    I don't think promises are more or less coupled than callbacks, just about the same.

    Promises however have other benefits:

    • If you expose a callback, you have to document whether it will be called once (like in jQuery.ajax) or more than once (like in Array.map). Promises are called always once.

    • There's no way to call a callback throwing and exception on it, so you have to provide another callback for the error case.

    • Just one callback can be registered, more than one for promises, and you can register them AFTER the event and you will get called anyway.

    • In a typed declaration (Typescript), Promise make easier to read the signature.

    • In the future, you can take advantage of an async / yield syntax.

    • Because they are standard, you can make reusable components like this one:

       disableScreen<T>(promiseGenerator: () => Promise<T>) : Promise<T>
       {
           //create transparent div
           return promiseGenerator.then(val=>
           {
              //remove transparent div
              return val;
           }, error=>{
               //remove transparent div
               throw error;
           });
       }
      
       disableScreen(()=>$.ajax(....));
      

    More on that: http://www.html5rocks.com/en/tutorials/es6/promises/

    EDIT:

    • Another benefit is writing a sequence of N async calls without N levels of indentation.

    Also, while I still don't think it's the main point, now I think they are a little bit more loosely coupled for this reasons:

    • They are standard (or at least try): code in C# or Java that uses strings are more lousy coupled than similar code in C++, because the different implementations of strings there, making it more reusable. Having an standard promise, the caller and the implementation are less coupled to each other because they don't have to agree on a (pair) of custom callbacks with custom parameters orders, names, etc... The fact that there are many different flavors on promises doesn't help thought.

    • They promote a more expression-based programming, easier to compose, cache, etc..:

        var cache: { [key: string] : Promise<any> };
      
        function getData(key: string): Promise<any> {
            return cache[key] || (cache[key] = getFromServer(key)); 
        }
      

    you can argue that expression based programming is more loosely coupled than imperative/callback based programming, or at least they pursue the same goal: composability.

    0 讨论(0)
提交回复
热议问题