“承诺”有什么好处? CommonJS 中的抽象?
我正在阅读这篇文章 关于承诺抽象的部分对我来说似乎有点过于复杂。下面给出了一个例子:
requestSomeData("http://example.com/foo") // returns a promise for the response
.then(function(response){ // ‘then’ is used to provide a promise handler
return JSON.parse(response.body); // parse the body
}) // returns a promise for the parsed body
.then(function(data){
return data.price; // get the price
}) // returns a promise for the price
.then(function(price){ // print out the price when it is fulfilled
print("The price is " + price);
});
在我看来,下面的代码可以用更少的代码行提供相同的结果:
requestSomeData("http://example.com/foo")
.requestHandler(function(response){
// parse the body
var data = JSON.parse(response.body);
// get the price
var price = data.price;
// print out the price
print("The price is " + price);
});
I'm reading this article and the section on the promise abstraction seems a little overly complicated to me. The following is given as an example:
requestSomeData("http://example.com/foo") // returns a promise for the response
.then(function(response){ // ‘then’ is used to provide a promise handler
return JSON.parse(response.body); // parse the body
}) // returns a promise for the parsed body
.then(function(data){
return data.price; // get the price
}) // returns a promise for the price
.then(function(price){ // print out the price when it is fulfilled
print("The price is " + price);
});
It seems to me that the following could provide the same result with fewer lines of code:
requestSomeData("http://example.com/foo")
.requestHandler(function(response){
// parse the body
var data = JSON.parse(response.body);
// get the price
var price = data.price;
// print out the price
print("The price is " + price);
});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
虽然两者最终确实会完成相同的事情,但区别在于您的第二个示例不是异步的。例如,考虑一下如果
JSON.parse(...)
结果是一个极其昂贵的操作会发生什么;你必须等待一切都完成,但这可能并不总是你想要的。这就是 Promise 给你带来的:将正确答案的计算推迟到更方便的时间的强大能力。顾名思义,该构造“承诺”在某个时刻给出结果,但不一定是现在。您可以在此处了解有关更大规模的 future 和 Promise 工作的更多信息。
While it is true that both will ultimately accomplish the same thing, the difference is that your second example is not asynchronous. For example, consider what happens if
JSON.parse(...)
turns out to be an extremely expensive operation; you'll have to hang until everything's finished, which may not always be what you want.That's what promises get you: the powerful ability to defer the computation of the right answer until a more convenient time. As the name suggests, the construct "promises" to give you the result at some point, just not necessarily right now. You can read more about futures and promises work on a larger scale here.
让我们将 Promise 示例与纯 Javascript 示例进行比较:
正如 Norbert Hartl 指出的那样,JSON.parse() 会因大字符串而挂起浏览器。所以我使用 setTimeout() 来延迟其执行(暂停 10 毫秒后)。这是 Kris Kowal 解决方案的一个示例。它允许当前的 Javascript 线程完成,从而在回调运行之前释放浏览器来呈现 DOM 更改并为用户滚动页面。
我希望commonjs的promise框架也使用像setTimeout这样的东西,否则文章示例中后面的promise确实会像担心的那样同步运行。
我上面的替代方案看起来相当难看,后面的过程需要进一步缩进。我重组了代码,以便我们可以在一个级别上提供所有流程链:
我希望证明 Javascript 中回调的传统前向传递几乎等同于 Promise。然而,经过两次尝试,我似乎已经证明,参考原始示例中代码的整洁性,承诺是一个更加优雅的解决方案!
Let's compare the promise example to a pure Javascript example:
As Norbert Hartl pointed out, JSON.parse() will hang the browser for large strings. So I used setTimeout() to delay its execution (after a pause of 10 milliseconds). This is one example of Kris Kowal's solution. It allows the current Javascript thread to complete, freeing up the browser to present DOM changes and scroll the page for the user, before the callback runs.
I hope the commonjs promise framework also uses something like setTimeout, otherwise the later promises in the article's example will indeed run synchronously as feared.
My alternative above looks pretty ugly, with the later processes requiring further indentation. I restructured the code, so that we can provide our process chain all in one level:
I was hoping to demonstrate that traditional forward-passing of callbacks in Javascript is pretty much equivalent to promises. However after two attempts I appear to have shown, with reference to the neatness of the code in the original example, that promises are a far more elegant solution!
第二个片段容易受到拒绝服务攻击,因为 example.com/foo 只能返回无效的 json 来导致服务器崩溃。即使是空响应也是无效的 JSON(尽管是有效的 JS)。这就像带有明显 SQL 注入漏洞的
mysql_*
示例。并且承诺代码也可以得到很大的改进。它们是相等的:
并且:
如果我们想要处理错误,那么它们将是相等的:
并且:
The second snippet is vulnerable to denial of service attack because example.com/foo can just return invalid json to crash the server. Even empty response is invalid JSON (though valid JS). It's like
mysql_*
examples with glaring SQL injection holes.And the promise code can be improved much as well. These are equal:
And:
If we wanted to handle the error, then these would be equal:
and:
人们还可能会补充说,第一个版本相对于第二个版本的优点是它分离了细化链中的不同操作(函数也不必就地编写)。第二个版本将低级解析与应用程序逻辑混合在一起。具体来说,使用 SOLID 原则作为指导方针,第二个版本违反了 OCP 和 SRP。
One might also add that the advantage of the first version over the second is that it separates different operations in the refinement chain (the functions don't have to be written in-place either). The second version mixes both the low-level parsing with application logic. Specifically, using the SOLID principles as guidelines, the second version violates both OCP and SRP.