我已经开发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
});
});
});
代码更多,可读性更差。我在这里没有获得任何东西,它也没有突然神奇地“变平”。更不用说把事情变成承诺了。
那么,承诺有什么好大惊小怪的呢?
除了已经确定的答案,用ES6箭头函数承诺从一个适度发光的小蓝矮星直接变成一个红巨星。它即将坍缩成超新星:
api().then(result => api2()).then(result2 => api3()).then(result3 => console.log(result3))
正如oligofren指出的,如果api调用之间没有参数,你根本不需要匿名包装器函数:
api().then(api2).then(api3).then(r3 => console.log(r3))
最后,如果你想达到超大质量黑洞的水平,你可以期待:
async function callApis() {
let api1Result = await api();
let api2Result = await api2(api1Result);
let api3Result = await api3(api2Result);
return api3Result;
}
除了已经确定的答案,用ES6箭头函数承诺从一个适度发光的小蓝矮星直接变成一个红巨星。它即将坍缩成超新星:
api().then(result => api2()).then(result2 => api3()).then(result3 => console.log(result3))
正如oligofren指出的,如果api调用之间没有参数,你根本不需要匿名包装器函数:
api().then(api2).then(api3).then(r3 => console.log(r3))
最后,如果你想达到超大质量黑洞的水平,你可以期待:
async function callApis() {
let api1Result = await api();
let api2Result = await api2(api1Result);
let api3Result = await api3(api2Result);
return api3Result;
}
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 );
...
}
不可否认,这比使用回调可读性强得多。
没有承诺只是回调的包装
例子
你可以在node js中使用javascript原生承诺
my cloud 9 code link : https://ide.c9.io/adx2803/native-promises-in-node
/**
* Created by dixit-lab on 20/6/16.
*/
var express = require('express');
var request = require('request'); //Simplified HTTP request client.
var app = express();
function promisify(url) {
return new Promise(function (resolve, reject) {
request.get(url, function (error, response, body) {
if (!error && response.statusCode == 200) {
resolve(body);
}
else {
reject(error);
}
})
});
}
//get all the albums of a user who have posted post 100
app.get('/listAlbums', function (req, res) {
//get the post with post id 100
promisify('http://jsonplaceholder.typicode.com/posts/100').then(function (result) {
var obj = JSON.parse(result);
return promisify('http://jsonplaceholder.typicode.com/users/' + obj.userId + '/albums')
})
.catch(function (e) {
console.log(e);
})
.then(function (result) {
res.end(result);
}
)
})
var server = app.listen(8081, function () {
var host = server.address().address
var port = server.address().port
console.log("Example app listening at http://%s:%s", host, port)
})
//run webservice on browser : http://localhost:8081/listAlbums