promises

    技术2022-07-11  138

    promises

    You've probably heard the talk around the water cooler about how promises are the future. All of the cool kids are using them, but you don't see what makes them so special. Can't you just use a callback? What's the big deal? In this article, we'll look at what promises are and how you can use them to write better JavaScript.

    您可能已经听过关于饮水机的话题,关于未来的前景如何。 所有很酷的孩子都在使用它们,但是您看不出是什么让它们如此特别。 您不能只使用回调吗? 有什么大不了的? 在本文中,我们将研究什么是Promise,以及如何使用它们来编写更好JavaScript。

    承诺更容易阅读 (Promises are Easier to Read)

    Let's say we want to grab some data from the HipsterJesus API and add it to our page. This API responds with data that looks like this:

    假设我们要从HipsterJesus API中获取一些数据并将其添加到我们的页面中。 该API响应的数据如下所示:

    { "text": "<p>Lorem ipsum...</p>", "params": { "paras": 4, "type": "hipster-latin" } }

    Using a callback, we'd write something like this:

    使用回调,我们将编写如下内容:

    $.getJSON('http://hipsterjesus.com/api/', function(data) { $('body').append(data.text); });

    If you're experienced with jQuery, you'll recognize we're making a GET request and expecting JSON in the response body. We're also passing in a callback function that takes the response JSON and adds it to the document.

    如果您有使用jQuery的经验,您将认识到我们正在发出GET请求,并且期望在响应主体中使用JSON。 我们还传递了一个回调函数,该函数采用响应JSON并将其添加到文档中。

    Another way to write this is to use the promise object returned by the getJSON method. You can attach a callback to this object directly.

    另一种写方法是使用getJSON方法返回的promise对象。 您可以将回调直接附加到该对象。

    var promise = $.getJSON('http://hipsterjesus.com/api/'); promise.done(function(data) { $('body').append(data.text); });

    Like the callback example, this appends the result of the API request to the document when the request is successful. But what happens if the request fails? We can also attach a fail handler to our promise.

    像回调示例一样,当请求成功时,这会将API请求的结果附加到文档中。 但是,如果请求失败了怎么办? 我们还可以为我们的承诺附加fail处理程序。

    var promise = $.getJSON('http://hipsterjesus.com/api/'); promise.done(function(data) { $('body').append(data.text); }); promise.fail(function() { $('body').append('

    Oh no, something went wrong!

    '); });

    Most people remove the promise variable, which makes it a little easier to tell what the code does at a glance.

    大多数人都删除了promise变量,这样一眼就能看出代码的作用。

    $.getJSON('http://hipsterjesus.com/api/') .done(function(data) { $('body').append(data.text); }) .fail(function() { $('body').append('

    Oh no, something went wrong!

    '); });

    jQuery also includes an always event handler that's called regardless if the request succeed or fails.

    jQuery还包括一个always事件处理程序,无论请求成功还是失败,都将调用该事件处理程序。

    $.getJSON('http://hipsterjesus.com/api/') .done(function(data) { $('body').append(data.text); }) .fail(function() { $('body').append('

    Oh no, something went wrong!

    '); }) .always(function() { $('body').append('

    I promise this will always be added!.

    '); });

    With promises, the order of the callbacks is respected. We're guaranteed to have our done callback called first, then our fail callback, and finally our always callback.

    使用promise,将遵守回调的顺序。 我们保证首先调用done回调,然后调用fail回调,最后调用always调用。

    更好的API (Better APIs)

    Let's say we want to create a wrapper object for the HipsterJesus API. We'll add a method, html, to return the HTML data that comes down from the API. Rather than having this method take in a handler that's called when the request is resolved, we can just have the method return a promise object.

    假设我们要为HipsterJesus API创建包装对象。 我们将添加一个方法html ,以返回来自APIHTML数据。 与其让该方法接受在解决请求时调用的处理程序,不如让该方法返回一个Promise对象。

    var hipsterJesus = { html: function() { return $.getJSON('http://hipsterjesus.com/api/').then(function(data) { return data.text; }); } };

    The cool thing about this is we can pass around our promise object without worrying about when or how it resolves its value. Any code that needs the return value of the promise can just register a callback with done.

    与此有关的很酷的事情是,我们可以绕过我们的Promise对象,而不必担心它何时或如何解决其价值。 任何需要Promise返回值的代码都可以使用done注册一个回调。

    The then method allows us to modify the result of a promise and pass it to the next handler in the chain. This means we can now use our new API like this:

    then方法允许我们修改promise的结果并将其传递给链中的下一个处理程序。 这意味着我们现在可以像这样使用我们的新API:

    hipsterJesus.html().done(function(html) { $("body").append(html); });

    Until recently, one of the killer features of AngularJS was that templates could bind directly to promises. In an Angular controller, this looked like:

    直到最近 ,AngularJS的杀手级功能之一就是模板可以直接绑定到Promise。 在Angular控制器中,这看起来像:

    $scope.hipsterIpsum = $http.get('http://hipsterjesus.com/api/');

    Then, it was as simple as writing {{ hipsterIpsum.text }} in a template. When the promise resolved, Angular would automatically update the view. Unfortunately, the Angular team has deprecated this feature. For now, it can be enabled by calling $parseProvider.unwrapPromises(true). I hope Angular and other frameworks include this feature going forward (I'm looking at you Ember).

    然后,这就像在模板中编写{{ hipsterIpsum.text }}一样简单。 承诺解决后,Angular会自动更新视图。 不幸的是,Angular团队不赞成使用此功能。 现在,可以通过调用$parseProvider.unwrapPromises(true)启用它。 我希望Angular和其他框架包括此功能(我正在为您提供Ember)。

    链式 (Chaining)

    The best part about promises is you can chain them! Let's say we want to add a method to our API that returns an array of paragraphs.

    关于承诺的最好的部分是您可以将它们链接起来! 假设我们要向API添加一个方法,该方法返回一个段落数组。

    var hipsterJesus = { html: function() { return $.getJSON('http://hipsterjesus.com/api/').then(function(data) { return data.text; }); }, paragraphs: function() { return this.html().then(function(html) { return html.replace(/<[^>]+>/g, "").split(""); }); } };

    We've left our HTML method the same, and we're using it in the paragraphs method. Because the return value of a promise's callback is passed to the next callback in the chain, we're free to create small, functional methods that change the data as it's passed through them.

    我们将HTML方法保持不变,并在paragraphs方法中使用它。 因为promise回调的返回值将传递到链中的下一个回调,所以我们可以自由地创建小的,实用的方法,这些方法会在数据通过它们时进行更改。

    We can chain promises as many times as we want. Let's add a method for sentences.

    我们可以根据需要多次链接承诺。 让我们为句子添加一个方法。

    var hipsterJesus = { html: function() { return $.getJSON('http://hipsterjesus.com/api/').then(function(data) { return data.text; }); }, paragraphs: function() { return this.html().then(function(html) { return html.replace(/<[^>]+>/g, "").split(""); }); }, sentences: function() { return this.paragraphs().then(function(paragraphs) { return [].concat.apply([], paragraphs.map(function(paragraph) { return paragraph.split(/. /); })); }); } };

    多次通话 (Multiple calls)

    Probably the most notable feature of promises is the ability to combine multiple API calls. When using callbacks, what happens if you need to make two API calls at once? You'll probably end up writing something like this:

    许诺最显着的功能可能是能够组合多个API调用。 使用回调时,如果您需要一次进行两个API调用,会发生什么情况? 您可能最终会写出这样的内容:

    var firstData = null; var secondData = null; var responseCallback = function() { if (!firstData || !secondData) return; // do something } $.get("http://example.com/first", function(data) { firstData = data; responseCallback(); }); $.get("http://example.com/second", function(data) { secondData = data; responseCallback(); });

    With promises, this becomes much easier:

    有了诺言,这变得容易得多:

    var firstPromise = $.get("http://example.com/first"); var secondPromise = $.get("http://example.com/second"); $.when(firstPromise, secondPromise).done(function(firstData, secondData) { // do something });

    Here, we're using the when method to attach a handler that's called when both requests are done.

    在这里,我们使用when方法来附加一个处理程序,当两个请求都完成时,该处理程序将被调用。

    结论 (Conclusion)

    That's it! Hopefully you have a sense of some of the awesome things you can accomplish with promises. What's your favorite way to use them? Let me know in the comments!

    而已! 希望您对可以通过诺言完成的一些很棒的事情有所了解。 您最喜欢使用它们的方式是什么? 在评论中让我知道!

    *Note: For simplicity, this article is using jQuery's deferred implementation. There are subtle differences between jQuery's Deferred object and the Promises/A+ specification, which is a more canonical standard. For more information, check out Q's Coming from jQuery wiki.

    *注意:为简单起见,本文使用jQuery的延迟实现。 jQuery的Deferred对象与Promises / A +规范 (这是一个更为规范的标准)之间存在细微的差异。 有关更多信息,请查看jQuery Wiki中的 Q's Coming 。

    翻译自: https://davidwalsh.name/write-javascript-promises

    promises

    相关资源:jdk-8u281-windows-x64.exe
    Processed: 0.011, SQL: 10