Promise构造函数的反模式
先从一个例子来看看Promise的常见的使用错误。
Bad Code
1 | // Bad example! Spot 3 mistakes! |
错误解析
The first mistake is to not chain things together properly. This happens when we create a new promise but forget to return it. As a consequence, the chain is broken, or rather, we have two independent chains racing. This means
doFourthThing()
won’t wait fordoSomethingElse()
ordoThirdThing()
to finish, and will run in parallel with them, likely unintended. Separate chains also have separate error handling, leading to uncaught errors.(这样会导致多个独立的Promise
链并行运行,而且不同的链需要不同的错误处理,这样会导致一些我们没有预期的错误。)The second mistake is to nest unnecessarily, enabling the first mistake. Nesting also limits the scope of inner error handlers, which—if unintended—can lead to uncaught errors. A variant of this is the promise constructor anti-pattern, which combines nesting with redundant use of the promise constructor to wrap code that already uses promises.(第二个错误是不必要的嵌套,会诱发第一个问题,而且也有错误处理问题,一个变体就是
promise 构造函数反模式
,这个我会在下面给出示例)The third mistake is forgetting to terminate chains with
catch
. Unterminated promise chains lead to uncaught promise rejections in most browsers.(第三个错误就是没有用catch来终止promise
链)
Good Code
1 | doSomething() |
反模式定义
下面来说说Promise的构造函数反模式
,这是它的定义which combines nesting with redundant use of the promise constructor to wrap code that already uses promises.
Example1:
1 | function getStuffDone(param) { |
Iview admin中对反模式的使用
另外再看一下iview admin
中的应用(我只想说这个代码写的好迷呀🙄),违反了上面的注意事项,有两条不同的链,而且如果其中一个函数出错,那么肯定是没有得到处理,我觉得如果使用的化,最起码在两处加上catch
语句。
1 | this.handleLogin({ userName, password }).then(res => { |
Vuex
中的代码(代码里加了注释)
1 | handleLogin ({ commit }, { userName, password }) { |
总结
Quoting Esailija:
This is the most common anti-pattern. It is easy to fall into this when you don’t really understand promises and think of them as glorified event emitters or callback utility. Let’s recap: promises are about making asynchronous code retain most of the lost properties of synchronous code such as flat indentation and one exception channel.
参考文章:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise
https://stackoverflow.com/questions/23803743/what-is-the-explicit-promise-construction-antipattern-and-how-do-i-avoid-it
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Using_promises