我已经开发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
});
});
});
代码更多,可读性更差。我在这里没有获得任何东西,它也没有突然神奇地“变平”。更不用说把事情变成承诺了。
那么,承诺有什么好大惊小怪的呢?
Promises允许程序员编写比使用回调更简单、更易读的代码。
在一个程序中,有一系列的步骤需要执行。
function f() {
step_a();
step_b();
step_c();
...
}
每一步之间通常都有信息传递。
function f() {
const a = step_a( );
const b = step_b( a );
const c = step_c( b );
...
}
其中一些步骤可能会花费(相对)较长的时间,所以有时您希望与其他事情并行执行这些步骤。一种方法是使用线程。另一个是异步编程。(这两种方法各有利弊,这里不再讨论。)这里,我们讨论的是异步编程。
在使用异步编程时,实现上述目标的简单方法是提供一个回调函数,在步骤完成时调用它。
// step_* calls the provided function with the returned value once complete.
function f() {
step_a(
function( a )
step_b(
function( b )
step_c(
...
)
},
)
},
)
}
这很难读懂。承诺提供了一种简化代码的方法。
// step_* returns a promise.
function f() {
step_a()
.then( step_b )
.then( step_c )
...
}
返回的对象被称为promise,因为它代表了函数的未来结果(即承诺的结果)(可以是值或异常)。
尽管承诺很有帮助,但使用承诺还是有点复杂。这就是async和await的用武之地。在声明为async的函数中,可以使用await来代替then。
// step_* returns a promise.
async function f()
const a = await step_a( );
const b = await step_b( a );
const c = await step_c( b );
...
}
不可否认,这比使用回调可读性强得多。