我使用热门节点库got向JSON API发出简单的GET
请求。
我有一个抽象请求的函数,如下所示:
function performRequest(url) {
got(url, {
json: true
}).then(function (response) {
return formatResponse(response.body);
}).catch(function (error) {
console.log(error.response.body);
});
}
formatResponse
是一个简单的同步方法,可以修改从API返回的JSON。
我希望能够从另一个函数调用performRequest
,然后使用返回值(一旦解析)。目前,由于performRequest
未被识别为异步方法,因此我的代码会调用它,然后立即继续。
function myBigFunction() {
var url = composeUrl();
var res = performRequest(url);
doMoreStuffWithResponse(res);
}
我知道我需要使用Promise
,但是,我总是不清楚如何将Promise与已经使用Promise的内置库函数结合使用(如在这种情况下)。
我也完全敞开心扉,认为这一切都是错误的。在这种情况下,我会很感激一些重定向。
感谢您的时间。
答案 0 :(得分:3)
了解Promise 是什么。它是值,你可以这样对待它。为了“读取”该值,您将函数传递给Promise的then
方法。您不需要myBigFunction
。在Promise结算后你想要运行的任何东西都需要传递给then
:
var req = performRequest(composeURL());
req.then(doStuffWithResponse);
现在,虽然我经常这样做,但我并不特别关心这种方式。我更喜欢使用接受承诺的函数并调用他们的then
方法:
var takesAPromise = function(p) {
return p.then(/* does stuff */);
};
请注意,它会返回已完成任务的Promise。但我更喜欢的是ES6单线:
let wrap = f => p => p.then(val => f.call(null, val));
现在您可以包装任意函数以将Promises作为输入并将它们作为输出返回。如果Promises是monad,那么这将是他们的bind
函数。使其与任意arity的功能无缝地工作留给读者练习。
答案 1 :(得分:1)
您总是希望return
履行您的职责承诺:
function performRequest(url) {
return got(url, {
//^^^^^^
json: true
}).then(function(response) {
return formatResponse(response.body);
}, function(error) {
throw new Error(error.response.body);
});
}
有了这个,你可以使用另一个then
:
function myBigFunction() {
var url = composeUrl();
var promise = performRequest(url);
return promise.then(function(res) {
return doMoreStuffWithResponse(res);
});
}
或简而言之
function myBigFunction() {
return performRequest(composeUrl()).then(doMoreStuffWithResponse);
}
以便您可以像
一样调用它myBigFunction().catch(function(error) {
console.log(error.message);
});