我正在尝试在 Node.js 中处理 JS Promise,但没有找到在不同函数之间传递 Promise 的解决方案。
任务
对于主要逻辑,我需要从 REST API 获取 items 的 json 对象。 API 处理本身位于 api.js
文件中。
对其中API的请求是通过request-promise发出的模块。我有一个私有(private) makeRequest
函数和公共(public)辅助函数,例如 API.getItems()
。
index.js
中的主要逻辑需要等待API函数才能执行。
问题
- promise 传递确实有效,但我不确定这是否不仅仅是巧合。返回一个返回
makeRequest
中响应的 Promise 是否正确? - 我真的需要所有 promise 才能使主要逻辑仅在等待项目设置后才起作用吗?有没有更简单的方法?
- 我仍然需要弄清楚如何最好地处理来自 a) makeRequest 和 b) getItems 函数的错误。 Promise 的最佳实践是什么?传递错误对象?
这是我现在想出的代码:
// index.js
var API = require('./lib/api');
var items;
function mainLogic() {
if (items instanceof Error) {
console.log("No items present. Stopping main logic.");
return;
}
// ... do something with items
}
API.getItems().then(function (response) {
if (response) {
console.log(response);
items = response;
mainLogic();
}
}, function (err) {
console.log(err);
});
api.js
// ./lib/api.js
var request = require('request-promise');
// constructor
var API = function () {
var api = this;
api.endpoint = "https://api.example.com/v1";
//...
};
API.prototype.getItems = function () {
var api = this;
var endpoint = '/items';
return new Promise(function (resolve, reject) {
var request = makeRequest(api, endpoint).then(function (response) {
if (200 === response.statusCode) {
resolve(response.body.items);
}
}, function (err) {
reject(false);
});
});
};
function makeRequest(api, endpoint) {
var url = api.endpoint + endpoint;
var options = {
method: 'GET',
uri: url,
body: {},
headers: {},
simple: false,
resolveWithFullResponse: true,
json: true
};
return request(options)
.then(function (response) {
console.log(response.body);
return response;
})
.catch(function (err) {
return Error(err);
});
}
module.exports = new API();
更多背景: 首先我开始使用 request 发出 API 请求模块,与回调一起使用。由于这些被称为异步,因此这些项目从未进入主逻辑,我过去常常使用 Promises 来处理它。
最佳答案
你在这里遗漏了两件事:
- 您可以直接链接 promise 并且
- Promise 错误处理的工作方式。
您可以将 makeRequest()
中的 return 语句更改为:
return request(options);
由于 makeRequest()
返回一个 Promise,因此您可以在 getItems()
中重用它,而不必显式创建新的 Promise。 .then()
函数已经为您完成了此操作:
return makeRequest(api, endpoint)
.then(function (response) {
if (200 === response.statusCode) {
return response.body.items;
}
else {
// throw an exception or call Promise.reject() with a proper error
}
});
如果 makeRequest()
返回的 Promise 被拒绝,并且您不处理拒绝(如上面的代码所示),则 .then()
返回的 Promise 也将被拒绝。您可以将该行为与异常进行比较。如果你没有捕捉到,它就会在调用堆栈中冒泡。
最后,在 index.js
中,您应该像这样使用 getItems()
:
API.getItems().then(function (response) {
// Here you are sure that everything worked. No additional checks required.
// Whatever you want to do with the response, do it here.
// Don't assign response to another variable outside of this scope.
// If processing the response is complex, rather pass it to another
// function directly.
}, function (err) {
// handle the error
});
我推荐这篇博文,以更好地理解 promise 的概念:
https://blog.domenic.me/youre-missing-the-point-of-promises/
关于javascript - JS Promise 在函数之间传递/等待 Promise,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34674926/