在 Promises 中编写更规范的 JavaScript 代码

发布于 2018-06-28 10:06:17 字数 4832 浏览 1707 评论 0

你可能听说过周围的人谈 Promises 的未来是怎样的。 所有时尚的年轻人使用它们,但你看不到是什么让他们如此特别。 你不能只使用一个回调函数,在这篇文章中,我们将看看什么是 Promises,以及如何使用它们来编写更好的 JavaScript 。

Promises 更容易阅读

比方说,我们要抓住一些 HipsterJesus API 的数据,并将其添加到我们的页面。 这个 API 响应的数据看起来像这样:

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

使用回调,我们会写这样的代码:

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

如果你使用过 jQuery,那么你会知道我们正在做一个 GET 请求,并期待在 JSON 响应正文。 我们还传递一个回调函数,它的响应 JSON 并将其添加到文档中。 另一种方式来写,这是使用由返回的 Promise 对象的 getJSON 方法。 你可以直接连接一个回调到这个对象。

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

像回调示例中,该附加的 API 请求的结果到该文件时,请求是成功的。 但是如果请求失败会发生什么? 我们还可以附加一个 fail 处理程序,以我们的 Promises。

var promise = $.getJSON('http://hipsterjesus.com/api/');

promise.done(function(data) {
  $('body').append(data.text);
});

promise.fail(function() {
  $('body').append('<p>Oh no, something went wrong!</p>');
});

大多数人除去 promise 的变量,这使得它更容易一些,告诉一下代码的作用一目了然。

$.getJSON('http://hipsterjesus.com/api/')

.done(function(data) {
  $('body').append(data.text);
})

.fail(function() {
  $('body').append('<p>Oh no, something went wrong!</p>');
});

jQuery 的还包括一个 always 这就是所谓的不管,如果请求成功或失败的事件处理程序。

$.getJSON('http://hipsterjesus.com/api/')

.done(function(data) {
  $('body').append(data.text);
})
.fail(function() {
  $('body').append('<p>Oh no, something went wrong!</p>');
})
.always(function() {
  $('body').append('<p>I promise this will always be added!.</p>');
});

使用 Promises 回调的顺序得到尊重。 我们保证有我们 done 所谓的先回调,那么我们 fail 的回调,最后我们 always 回调。

更好的API

比方说我们要创建一个包装对象的 HipsterJesus 的 API。 我们将添加一个方法 html() ,以返回来自 API 下来的HTML数据。 而不是这种方法需要在这就是所谓的请求时解决处理,我们只要有方法返回一个 Promise 对象。

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

这个很酷的事情是我们可以通过我们的周围物体的 Promises,而不必担心何时或如何解决它的价值。 需要 Promises 的返回值的任何代码就可以只登记一个回调 done 。 在 then 方法允许我们修改一个 Promises 的结果,并将它传递给链中的下一个处理程序。 这意味着我们现在可以使用我们喜欢这个新的 API:

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

直到最近 ,中 AngularJS 的杀手锏之一就是模板可以直接绑定到 Promises。 在一个角控制器,这看起来像:

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

那么它是那样简单写 {{ hipsterIpsum.text }} 在模板中。 当 Promises 解决角度会自动更新视图。 不幸的是,角队弃用此功能。 现在它可以通过调用启用 $parseProvider.unwrapPromises(true) 。 我希望角和其他框架包含此功能前进。

链接

关于 Promises 的最好的部分是可以随时修改和定义多个方法,比方说我们要一个方法添加到我们的 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("");
    });
  }
};

我们已经离开了我们的 HTML 的方法是相同的,而我们用它在 paragraphs 的方法。 因为 Promises 的回调的返回值传递给链中的下一个回调,我们可以自由地创建更改数据,因为它是通过它们体积小巧,功能的方法。 我们可以 Promises 链,因为我们希望尽可能多的时间。 让我们添加的句子的方法。

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(/. /);
      }));
    });
  }
};

多次调用

可能 Promises 的最显着特点是将多个 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();
});

有了  Promises,这变得容易多了:

var firstPromise = $.get("http://example.com/first");
var secondPromise = $.get("http://example.com/second");

$.when(firstPromise, secondPromise).done(function(firstData, secondData) {
  // do something
});

在这里,我们使用 when 方法来附加一个这就是所谓的当两个请求进行处理。 结论就是这样! 希望你有一些真棒事情可以做到的 Promises 感受。

什么是你最喜欢的方式来使用它们呢? 让我知道在评论!

注:为简单起见,本文使用jQuery的延迟实现。 有jQuery的细微差异Deferred对象和Promises/A+规范 ,这是一个比较规范的标准。 欲了解更多信息,请查看Q'S 从jQuery的维基即将 。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

关于作者

JSmiles

生命进入颠沛而奔忙的本质状态,并将以不断告别和相遇的陈旧方式继续下去。

0 文章
0 评论
84960 人气
更多

推荐作者

qq_Yqvrrd

文章 0 评论 0

2503248646

文章 0 评论 0

浮生未歇

文章 0 评论 0

养猫人

文章 0 评论 0

第七度阳光i

文章 0 评论 0

新雨望断虹

文章 0 评论 0

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文