是否可以在不向控制台发送错误消息的情况下停止链?

Can a chain be stopped without sending an error message to the console?

使用以下代码,当我拒绝承诺时,我看到第一个 console.log,但我也看到第二个 console.log。这是预料之中的,因为拒绝只会影响下一个 "then()".

问题是,循环中有没有等价于一个"break"的运算符,可以跳链?快速的答案是肯定的,使用未捕获的 reject() 或 throw(),但这两种方法都会向控制台发送错误消息(它们会停止整个代码执行吗?)

那么问题来了,能不能做到"cleanly"?

*我的第一个假设是,通过捕捉 reject/error 就可以了,但事实并非如此

Promise.resolve()
.then(function(){
  do stuff
  return Promise.resolve();
})
.then(function(){
  if (a === 'this')
    return Promise.resolve();
  else
    // is there any "break" equivalent here?
    return Promise.reject();
})
.then(function(){
  console.log('seen if not rejected');
},function(){
  console.log('seen if rejected');
})
.then(function(){
  console.log('seen all the time');
});

当您将第二个参数(onRejected 函数)传递给 then 方法时,实际上会捕获拒绝。它 returns 也是一个承诺,因此您可以继续链接。

如果您删除第三个 then 中的 onRejected 函数,您将在控制台中看到未捕获的异常,例如:

Promise.reject()
  .then(function(){
    console.log('resolved');
  })
  .then(function(){
    console.log('you cannot see me');
  })

// Uncaught (in promise)

是的,你可以 catch 异常,如果它没有被 onRejected:

捕获
Promise.reject()
  .then(function(){
    console.log('resolved');
  })
  .catch(function(){
    console.log('you can see me');
  })

// you can see me


Promise.reject()
  .then(function(){
    console.log('resolved');
  }, function(){
    console.log('rejected');
  })
  .catch(function(){
    console.log('you cannot see me');
  })

// rejected

根据我的经验,在实际业务场景中,我们通常希望分离不相关的逻辑。所以我们会在 onRejected 中捕获拒绝,做一些事情,然后将异常抛给 catch 方法(在本身或在链接 then 中):

Promise.reject()
  .then(function(){
    console.log('resolved');
  }, function(e){
    console.log('rejected');
    throw e
  })
  .catch(function(){
    console.log('you can see me');
  })

// rejected
// you can see me

是因为你赶上了拒绝。下面两块是等价的:

示例 1

var stuff = function () {

};
var doStuff = function () {

};
var a = 'notThis';

Promise.resolve()
    .then(function () {
        doStuff();
        return Promise.resolve();
    })
    .then(function () {
        if (a === 'this')
            return Promise.resolve();
        else
            return Promise.reject();
    })
    .then(function () {
        stuff();
    }, function () {
        console.log('rejected, end of chain');
    })
    .then(function () {
        console.log('only executed if not rejected');
    });

例子2

var stuff = function () {

};
var doStuff = function () {

};
var a = 'notThis';

Promise.resolve()
    .then(function () {
        doStuff();
        return Promise.resolve();
    })
    .then(function () {
        if (a === 'this')
            return Promise.resolve();
        else
            return Promise.reject();
    })
    .then(function () {
        stuff();
    })
    .catch(function () {
        console.log('rejected, end of chain');
    })
    .then(function () {
        console.log('only executed if not rejected');
    });

两个 .then(success, error) 回调 return 承诺。

即:

Promise.reject()

.then(function () {
  // won't be called, as above promise is rejected
}, function () {
  // will be called, and returns a resolved promise by default;
  // if you want the next error callback to be called,
  // you need to return a rejected promise or to throw an error
})

.then(function () {
  // 1: called if above .then returns a resolved promise
}, function () {
  // 2: called if above .then returns a rejected promise or throws an error
})