我已经开发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
});
});
});
代码更多,可读性更差。我在这里没有获得任何东西,它也没有突然神奇地“变平”。更不用说把事情变成承诺了。
那么,承诺有什么好大惊小怪的呢?
没有承诺只是回调的包装
例子
你可以在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
承诺不是回调。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
});
几乎和尝试{…} 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调用),但你需要等待这3个调用,那该怎么办?如果没有承诺,你就必须创造出某种反击。有了承诺,使用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.
});
希望你现在能从新的角度看待承诺。