很奇怪(或者我不知道)承诺语法 - 完成,失败,完成

时间:2017-09-29 20:45:43

标签: javascript jquery promise

我遇到了下面的代码块...我不明白。我完全理解承诺(以及随之而来的一切):

deferred.then(successCb, errorCb);

但是,下面的代码似乎有三个回调(completefaildone),我不知道从哪里开始查看 - 我只能猜测一个可观察的 - 比如successfailurefinally模式,但似乎并非如此。

我查看了jQuery deferreds and promises - .then() vs .done()等随机问题和here等文档。文档似乎暗示complete甚至不是一个东西而且只有always(运行无论承诺是成功还是失败,在解决时),done('这将运行,如果$ .get成功' - 它的奇怪名称),fail(失败)条件。

 var promise = $.ajax({
    type: 'POST',
    url: 'www.foo.com',
    dataType: 'json',
    contentType: 'application/json; charset=utf-8',
    data: muhData
  });
  promise.complete(function(d) {
    console.debug("complete");
  }).fail(function(){
    console.error("failed!");
  }).done(function(d){
    console.log('Done');
  });

tl; dr:Wut代码吗?

1 个答案:

答案 0 :(得分:2)

.complete().done().fail()都是特定于jQuery的实现,不遵循承诺标准。 jQuery还支持jQuery 3.x中的.then(),他们试图使.then()符合promise标准。我建议你这样做:

 $.ajax({
    type: 'POST',
    url: 'www.foo.com',
    dataType: 'json',
    contentType: 'application/json; charset=utf-8',
    data: muhData
  }).then(function(d) {
    console.debug("complete");
  }, function() {
    console.error("failed!");
  });

或者,如果你被迫使用旧版本的jQuery并且想要符合标准的行为,你可以这样做:

 Promise.resolve($.ajax({
    type: 'POST',
    url: 'www.foo.com',
    dataType: 'json',
    contentType: 'application/json; charset=utf-8',
    data: muhData
  })).then(function(d) {
    console.debug("complete");
  }).catch(function() {
    console.error("failed!");
  });

这会将jQuery承诺强制转换为标准承诺,因此您可以使用标准.then().catch()逻辑,并且不会对其工作方式产生任何意外。

以下是来自jQuery docs.complete().done().fail()的更多信息:

不推荐使用

.complete(),而应使用.always()。无论承诺是履行还是拒绝(例如,它总是被称为),都会被称为。

.fail().catch()类似,因为当承诺拒绝时(尽管在所有方面都不相同),它会被调用。

.done()与传递给.then()的第一个参数类似,因为它在promise履行时被调用。

老实说,我不认为直接使用jQuery承诺逻辑是值得的,因为现在你可能在你的应用程序的其他地方有行业标准逻辑,并且使用两个稍微不同的实现是非常痛苦的。对于使用jQuery ajax的简单事情,我只是坚持使用.then()来实现jQuery的承诺。对于嵌套或链式承诺的更多涉及的事情,我使用Promise.resolve()转换为标准的承诺,因此我知道它在所有情况下将具有的确切行为,并且它将像我的代码中的所有其他承诺一样工作。