承诺不仅仅是回调吗?我已经开发了几年的JavaScript,我根本不理解有关承诺的大惊小怪。似乎我所做的只是改变:api(function(result){
api2(function(result2){
api3(function(result3){
// do work
});
});});无论如何,我可以使用像async这样的库,例如:api().then(function(result){
api2().then(function(result2){
api3().then(function(result3){
// do work
});
});});哪个代码更多,可读性更低。我没有在这里获得任何东西,它也不会突然神奇地“平坦”。更不用说必须将事物转换为承诺。那么,这里的承诺有什么大惊小怪?
4 回答
万千封印
TA贡献1891条经验 获得超3个赞
承诺不是回调。promise表示异步操作的未来结果。当然,按照你的方式写它们,你得到的好处不大。但是如果按照它们的使用方式编写它们,您可以以类似于同步代码的方式编写异步代码,并且更容易遵循:
api().then(function(result){ return api2();}).then(function(result2){ return api3();}).then(function(result3){ // do work});
当然,代码不多,但更具可读性。
但这不是结束。让我们发现真正的好处:如果您想检查任何步骤中的任何错误怎么办?用回调来做这件事就好了,但有了承诺,这是小菜一碟:
api().then(function(result){ return api2();}).then(function(result2){ return api3();}).then(function(result3){ // do work}).catch(function(error) { //handle any error that may occur before this point});
几乎和try { ... } catch
块一样。
更好的是:
api().then(function(result){ return api2();}).then(function(result2){ return api3();}).then(function(result3){ // do work}).catch(function(error) { //handle any error that may occur before this point}).then(function() { //do something whether there was an error or not //like hiding an spinner if you were performing an AJAX request.});
更妙的是:如果这3个调用api
,api2
,api3
可以同时运行(例如,如果他们是AJAX调用),但你需要等待三个?没有承诺,你应该创建某种计数器。承诺,使用ES6符号,是另一块蛋糕,非常整洁:
Promise.all([api(), api2(), api3()]).then(function(result) { //do work. result is an array contains the values of the three fulfilled promises.}).catch(function(error) { //handle the error. At least one of the promises rejected.});
希望你现在以新的眼光看待Promise。
牛魔王的故事
TA贡献1830条经验 获得超3个赞
除了已经建立的答案之外,凭借ES6箭头功能,Promise从一个中等闪亮的小蓝矮星直接变成一个红色巨人。那即将崩溃成超新星:
api().then(result => api2()).then(result2 => api3()).then(result3 => console.log(result3))
正如oligofren指出的那样,在api调用之间没有参数,你根本不需要匿名包装器函数:
api().then(api2).then(api3).then(r3 => console.log(r3))
最后,如果你想达到一个超大质量的黑洞水平,可以期待Promises:
async function callApis() { let api1Result = await api(); let api2Result = await api2(api1Result); let api3Result = await api3(api2Result); return api3Result;}
繁花如伊
TA贡献2012条经验 获得超12个赞
除了其他答案之外,ES2015语法与promises无缝融合,减少了更多的样板代码:
// Sequentially:api1() .then(r1 => api2(r1)) .then(r2 => api3(r2)) .then(r3 => { // Done });// Parallel:Promise.all([ api1(), api2(), api3()]).then(([r1, r2, r3]) => { // Done});
添加回答
举报
0/150
提交
取消