【问题标题】:reject handling in promises拒绝处理承诺
【发布时间】:2014-03-01 23:44:34
【问题描述】:

以下代码从每个 getJSON 方法返回一个 RSVP 承诺:

  getJSON('/login')
  .then(getJSON('/errors').then(function(users) {
    self.user = users;
  }))
  .then(getJSON('contacts').then(function(contacts) {
    self.contacts = contacts;
  }))
  .then(getJSON('companies').then(function(companies) {
    self.companies = companies;
    callback(self);
  }, function(err){
    console.log('does not get here')  
  }));

我对 Promise 的理解显然是错误的,我不想为每个 then 提供错误回调,而是认为错误会被转发到后续 then 函数之一中的下一个可用错误回调。

在上面的代码中,第 2 行的 getJSON 会被拒绝,但不会转发到最后的错误回调中。

我是否必须为每个然后提供一个错误回调。这似乎与回调地狱没有什么不同。

【问题讨论】:

    标签: javascript rsvp.js


    【解决方案1】:

    您是否有任何理由不一次发出所有请求?

    self.user = getJSON("login");
    self.contacts = getJSON("contacts");
    self.companies = getJSON("companies");
    // not sure what "/errors" does or what you assign it to, add it if you please
    
    //.hash will go through object properties and wait for all promises to resolve
    return RSVP.hash(self).then(function(results){
        //here, self now contains .user .contacts and .companies
        callback(self); //DO NOT do this, instead return the promise
    }).catch(function(err){
         //this is where all error handling goes
    });
    

    注意那里的return,最好返回承诺而不是调用回调,你可以从外部.then它。

    【讨论】:

      【解决方案2】:

      我认为您以错误的方式链接您的承诺。您的 getJSONS 在前一个完成后没有连续执行。 当您调用第一个 getJSON (getJSON('/login')) 时,您不会将两个处理程序传递给它的 then 方法。您正在传递一个新的 getJSON 调用。这意味着,就在对 getJSON 的调用完成之后(但在 ajax 调用结束之前),您正在执行第二个 getJSON (getJSON('/errors'))。您将生成的承诺作为 getJSON('/login') 的 then 方法的第一个参数传递。通过这样做,这个 Promise 将使用与 getJSON('/errors') 相同的值来解决或拒绝。好的,但是...

      .then(getJSON('companies').then(function(companies) {
          self.companies = companies;
          callback(self);
        }, function(err){
          console.log('does not get here')  
        }));
      

      这里你传递了一个新的promise,它由getJSON(companies) 作为then 方法的第一个参数返回。该方法所属的承诺,当被拒绝时,将尝试调用作为第二个参数传递的函数......但是没有!因此,因为 getJSON('companies') 不会拒绝,所以您不会收到错误消息。我重写了你的链:

      getJSON('/login').then(
        function(users) {
            self.user = users;
            return getJSON('/errors');
        }).then(function() {
            return getJSON('contacts')
        }).then(function(contacts) {
            self.contacts = contacts;
            return getJSON('companies');
        }).then(function(companies) {
            self.companies = companies;
            callback(self);
        }, function(err){
          console.log('does not get here')  
        });
      

      现在我认为它应该可以正常工作。在成功解析每个 Promise 后,将执行一个发出新 getJSON 请求的函数,并返回它的 Promise。如果其中任何一个拒绝,则拒绝将通过,直到找到带有第二个参数的 then,这发生在链的末端。最后一个函数(err) 将捕获在那之前出现的任何错误。

      【讨论】:

      • +1 这个答案看起来有正确的想法,请考虑澄清一下(目前有点“文字墙”)。另外,我更喜欢.catch 而不是,function(err){
      • 你是对的,但这里有点晚了。明天我会尽力解释得更好。顺便说一句,我不知道 RVSP 具体的 promises/A+ 实现,所以我不知道它有一个具体的 .catch() 方法。
      • 虽然并非所有的 Promise/A+ 实现都如此,但事实上绝大多数 Promise 库(以及 DOM 期货和原生 ES6 Promise)都有一个 .catch 方法。 Q$qRSVPBluebirdwhennative 都可以。
      • 我知道大多数人都这样做,但由于我不确定 RSVP,我决定不使用它。
      【解决方案3】:

      与 Benjamin Gruenbaum 的类似,但更简洁一些。

      return RSVP.hash({
        user: getJSON("login");
        contacts: getJSON("contacts");
        companies: getJSON("companies");
      }}).then(callback).catch(function(err){
           //this is where all error handling goes
      });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-03-31
        • 2023-03-17
        • 2018-04-01
        • 2021-09-19
        • 1970-01-01
        相关资源
        最近更新 更多