[译]Promise(Resolve|[译]Promise:Resolve 并不是 Reject 的对立面 - Jake Archibald)

原文链接https://jakearchibald.com/2014/resolve-not-opposite-of-reject/
第一次把Promise用在工作中时,我对它抱有这样一种简单的看法:把一个值传入reject()函数,这个promise就“失败”了;而把一个值传入resolve()函数那它就“成功”了。但是,后者却并不总是对的。

new Promise(function(resolve, reject) { resolve(something); }).then(function() { console.log("Yey"); }, function() { console.log("Boo"); });

我们并没有调用reject()函数,但当以下情况出现时,作为rejection回调的console.log("Boo"); 还是会被调用:
  • 参数something没有被定义。这样会导致错误的抛出,这个错误将被promise捕捉然后传入reject(),或者
  • 参数something是一个rejected状态的promise对象
于是:
new Promise(function(resolve, reject) { resolve(Promise.reject()); }).catch(function() { // 这个函数会被调用 });

这是一件好事,因为它的行为和Promise.resolve(),还有回调函数的返回值的行为一样:
var promise1 = Promise.resolve(Promise.reject()); var promise2 = Promise.resolve().then(function() { return Promise.reject(); }); var promise3 = Promise.reject().catch(function() { return Promise.reject(); });

上面的三个promise都将变成rejected状态,当你用then()方法去解析一个值时,你将会把这个操作推迟到最后一个非promise值(译注:此处原文When you resolve a value with a "then" method, you're deferring the resolution to the eventual non-promise value.
(译注:这些代码无法运行。原文评论区一位同学说明,如果一个Promise对象不立即调用then()catch()函数,浏览器将会抛出错误。他建议使用如下代码:
var promise1 = Promise.resolve(Promise.reject()).then(() => {}, (err) => { console.log(err); //undefined }); var promise2 = Promise.resolve().then(function() { return Promise.reject(); }).catch((err) => { console.log(err); //undefined }); var promise3 = Promise.reject().catch(function() { return Promise.reject(); }).then(() => {}, (err) => { console.log(err); //undefined });

这些代码也印证了作者的看法)
实践 根据Promise的这些特性,你完全可以去解析一个值而不必担心它到底是一个值呢,还是一个Promise呢,还是一个解析解析Promise的Promise的Promise呢,等等等等。(译注:2333,原文or a promise that resolves to a promise that resolves to a promise etc etc.)
function apiCall(method, params) { return new Promise(function(resolve, reject) { if (!method) { throw TypeError("apiCall: You must provide a method"); }var data = https://www.it610.com/article/{ jsonrpc:"2.0", method: method }if (params) { data.params = params; }resolve(postJSON('/my/api/', data)); }); }

【[译]Promise(Resolve|[译]Promise:Resolve 并不是 Reject 的对立面 - Jake Archibald)】现在不管是参数method没有传入,还是postJSON()方法被拒绝,又或者因为一些别的啥原因,apiCall都会reject()。你其实用Promise方案安全地封装了postJSON方法。

    推荐阅读