如何让 Javascript 在发送请求之前等待 Promise?
How to make Javascript wait for a Promise before sending a request?
我知道有很多基于 Promise 的问题和答案,但我想做的是用 axios 检索一些数据(到微服务),然后使用这些数据发送另一个请求(到不同的微服务)。
不知何故,我想出了如何设置我的请求:
screenshot from console with the request right before axios call
问题是在后端我只有前两个子句。我认为这是因为我使用了 async/await 以成功避免 Promise 并获得实际的 result/class。我的意思是,也许请求在 promise 完成之前发送,但是我如何在控制台中正确获取请求?
我是 Javascript 的新手,欢迎任何帮助。
编辑:
这是我的代码:
getServicesList = async (instanceIds) => {
return await FlowsInventoryAPI.searchServices(instanceIds, this.props.salesline, this.props.environment, this.props.sources, this.props.targets)
.then((response) => {
return response;
})
.catch((error) => {
Toastr.error(ResponseErrorProvider.getError(error));
if (ResponseErrorProvider.isUnauthorized(error)) {
Toastr.error(error.response.data.message);
this.props.onLogout();
}
});
}
上面那个是我讲的第一个电话。
buildSearchObject = (size, page, status) => {
let interval = TimestampUtils.getInterval(this.props.logsTimeInterval);
let from = interval.from * 1000;
let to = interval.to * 1000;
return {
fromMillis: from,
toMillis: to,
size: size,
page: page,
salesline: this.props.salesline,
environment: this.props.environment,
routes: this.props.routes,
sources: this.props.sources,
targets: this.props.targets,
customFilters: [...this.props.filters.values(), ...this.getEnabledAdvancedFilters().values()],
status: status === LogStatus.ALL ? "" : status,
sortFieldName: this.props.sortColumn,
order: this.props.sortOrder,
searchFilter: this.props.searchFilter,
searchFilterOperator: this.props.searchFilterOperator,
applications: this.props.applications,
openedStores: this.props.openedStores,
servicesPromise: this.state.servicesList // here is the promise
}
};
searchLogs = (size, page, status, callback) => {
loadingService.showLoadingModal("loadingLogsPage", this.props.location.pathname);
let searchObject = this.buildSearchObject(size, page, status);
ElasticSearchApi.search(searchObject, this.props.token)
.then(response => {
callback(response);
})
.catch((error) => {
loadingService.hideLoadingModal("loadingLogsPage", this.props.location.pathname);
Toastr.error(ResponseErrorProvider.getError(error));
if (ResponseErrorProvider.isUnauthorized(error)) {
Toastr.error(error.response.data.message);
this.props.onLogout();
}
});
};
我在上一段中进行了第二次调用,它调用了包含我们承诺的 buildSearchObject 方法。正如我告诉过你的,我想出了如何将它作为值发送,但我认为由于“异步性”,在调用第二次调用时我的承诺可能还没有准备好,这就是为什么我的代码具有状态承诺。
编辑 2:
constructor(props) {
super(props);
this.ongoingRequestId = undefined;
this.ongoingRequests = new Map();
this.state = {
servicesList: this.getServicesList(this.getInstanceIds())
}
}
这是我的构造函数,我在其中创建 this.state.servicesList.
在继续之前,您需要使用 await
关键字等待承诺响应。
// 1. Wait for create or update the customer before continuing
const customerId = await updateOrCreateCustomer(customerData);
// 2. Register sale, with customer created in previous section
const customerSale = sale(paymentMethod, customerId);
一些建议:
- 不要将传统的 promises 语法与 async / await 混合使用。它会让你的代码难以理解,即使你自己也是如此。不要将回调方法与承诺混合使用。选择一种方法并坚持下去。
- 如果你对 promise 有困难,强迫自己到处使用 async / await。在我看来,async / await 更容易理解,因为它不会破坏您的代码流。
例如,转换这个:
FlowsInventoryAPI.searchServices(/* params */)
.then((response) => /* response code */)
.catch((error) => /* error code */)
至:
try {
const response = await FlowsInventoryAPI.searchServices(/* params */);
/* response code */
} catch (error) {
/* error code */
}
- 不要像调用
this.getServicesList
那样使构造函数异步,因为您不能在构造函数中等待异步操作(如 getServicesList
)。请改用静态异步方法。
例如,转换这个:
class SomeObject extends Something {
constructor(props) {
super(props);
this.ongoingRequestId = undefined;
this.ongoingRequests = new Map();
this.state = {
servicesList: this.getServicesList(this.getInstanceIds())
}
}
}
至:
class SomeObject extends Something {
constructor(props) {
super(props);
this.ongoingRequestId = undefined;
this.ongoingRequests = new Map();
this.state = { servicesList: null };
}
async init() {
this.state.servicesList = await this.getServicesList(this.getInstanceIds());
}
static async create(props) {
const someObject = new SomeObject(props);
await someObject.init();
return someObject;
}
}
不要调用 const object = new SomeObject(props);
,而是调用 const object = await SomeObject.create(props);
我知道有很多基于 Promise 的问题和答案,但我想做的是用 axios 检索一些数据(到微服务),然后使用这些数据发送另一个请求(到不同的微服务)。
不知何故,我想出了如何设置我的请求:
screenshot from console with the request right before axios call
问题是在后端我只有前两个子句。我认为这是因为我使用了 async/await 以成功避免 Promise 并获得实际的 result/class。我的意思是,也许请求在 promise 完成之前发送,但是我如何在控制台中正确获取请求?
我是 Javascript 的新手,欢迎任何帮助。
编辑:
这是我的代码:
getServicesList = async (instanceIds) => {
return await FlowsInventoryAPI.searchServices(instanceIds, this.props.salesline, this.props.environment, this.props.sources, this.props.targets)
.then((response) => {
return response;
})
.catch((error) => {
Toastr.error(ResponseErrorProvider.getError(error));
if (ResponseErrorProvider.isUnauthorized(error)) {
Toastr.error(error.response.data.message);
this.props.onLogout();
}
});
}
上面那个是我讲的第一个电话。
buildSearchObject = (size, page, status) => {
let interval = TimestampUtils.getInterval(this.props.logsTimeInterval);
let from = interval.from * 1000;
let to = interval.to * 1000;
return {
fromMillis: from,
toMillis: to,
size: size,
page: page,
salesline: this.props.salesline,
environment: this.props.environment,
routes: this.props.routes,
sources: this.props.sources,
targets: this.props.targets,
customFilters: [...this.props.filters.values(), ...this.getEnabledAdvancedFilters().values()],
status: status === LogStatus.ALL ? "" : status,
sortFieldName: this.props.sortColumn,
order: this.props.sortOrder,
searchFilter: this.props.searchFilter,
searchFilterOperator: this.props.searchFilterOperator,
applications: this.props.applications,
openedStores: this.props.openedStores,
servicesPromise: this.state.servicesList // here is the promise
}
};
searchLogs = (size, page, status, callback) => {
loadingService.showLoadingModal("loadingLogsPage", this.props.location.pathname);
let searchObject = this.buildSearchObject(size, page, status);
ElasticSearchApi.search(searchObject, this.props.token)
.then(response => {
callback(response);
})
.catch((error) => {
loadingService.hideLoadingModal("loadingLogsPage", this.props.location.pathname);
Toastr.error(ResponseErrorProvider.getError(error));
if (ResponseErrorProvider.isUnauthorized(error)) {
Toastr.error(error.response.data.message);
this.props.onLogout();
}
});
};
我在上一段中进行了第二次调用,它调用了包含我们承诺的 buildSearchObject 方法。正如我告诉过你的,我想出了如何将它作为值发送,但我认为由于“异步性”,在调用第二次调用时我的承诺可能还没有准备好,这就是为什么我的代码具有状态承诺。
编辑 2:
constructor(props) {
super(props);
this.ongoingRequestId = undefined;
this.ongoingRequests = new Map();
this.state = {
servicesList: this.getServicesList(this.getInstanceIds())
}
}
这是我的构造函数,我在其中创建 this.state.servicesList.
在继续之前,您需要使用 await
关键字等待承诺响应。
// 1. Wait for create or update the customer before continuing
const customerId = await updateOrCreateCustomer(customerData);
// 2. Register sale, with customer created in previous section
const customerSale = sale(paymentMethod, customerId);
一些建议:
- 不要将传统的 promises 语法与 async / await 混合使用。它会让你的代码难以理解,即使你自己也是如此。不要将回调方法与承诺混合使用。选择一种方法并坚持下去。
- 如果你对 promise 有困难,强迫自己到处使用 async / await。在我看来,async / await 更容易理解,因为它不会破坏您的代码流。
例如,转换这个:
FlowsInventoryAPI.searchServices(/* params */)
.then((response) => /* response code */)
.catch((error) => /* error code */)
至:
try {
const response = await FlowsInventoryAPI.searchServices(/* params */);
/* response code */
} catch (error) {
/* error code */
}
- 不要像调用
this.getServicesList
那样使构造函数异步,因为您不能在构造函数中等待异步操作(如getServicesList
)。请改用静态异步方法。
例如,转换这个:
class SomeObject extends Something {
constructor(props) {
super(props);
this.ongoingRequestId = undefined;
this.ongoingRequests = new Map();
this.state = {
servicesList: this.getServicesList(this.getInstanceIds())
}
}
}
至:
class SomeObject extends Something {
constructor(props) {
super(props);
this.ongoingRequestId = undefined;
this.ongoingRequests = new Map();
this.state = { servicesList: null };
}
async init() {
this.state.servicesList = await this.getServicesList(this.getInstanceIds());
}
static async create(props) {
const someObject = new SomeObject(props);
await someObject.init();
return someObject;
}
}
不要调用 const object = new SomeObject(props);
,而是调用 const object = await SomeObject.create(props);