简体   繁体   English

如何让 Javascript 在发送请求之前等待 Promise?

[英]How to make Javascript wait for a Promise before sending a request?

I know there are many questions and answers based on Promise, but what I want to do is to retrieve some data with axios (to a microservice) and then to use this data in order to send another request (to a different microservice).我知道有很多基于 Promise 的问题和答案,但我想要做的是用 axios 检索一些数据(到微服务),然后使用这些数据发送另一个请求(到不同的微服务)。

Somehow, I figured out how to set my request:不知何故,我想出了如何设置我的请求:

screenshot from console with the request right before axios call在 axios 调用之前带有请求的控制台屏幕截图

The problem is that in backend I have only first two clauses.问题是在后端我只有前两个子句。 I think this is because I have used async/await in order to successfully avoid Promise and get the actual result/class.我认为这是因为我使用了 async/await 来成功避免 Promise 并获得实际结果/类。 What I meant is that, maybe the request is sent before the promise is fulfilled, but how do I correctly get the request in console?我的意思是,也许请求是在承诺完成之前发送的,但是如何在控制台中正确获取请求?

I am newbie into Javascript, so any helping hand is welcome.我是 Javascript 的新手,所以欢迎任何帮助。

EDIT:编辑:

Here is my code:这是我的代码:

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();
            }
        });
}

The above one is the first call I've talked about.上面是我谈到的第一个电话。

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();
                }
            });
    };

I have the second call in last paragraph which calls the buildSearchObject method which contains our promise.我在最后一段中进行了第二次调用,它调用了包含我们的承诺的 buildSearchObject 方法。 As I told you I figured out how to send it as value, but I think that because of "asynchronicity" maybe my promise is not ready yet in the moment when second call is called, this is why my code has the promise in state.正如我告诉你的,我想出了如何将它作为值发送,但我认为由于“异步性”,可能我的承诺在第二次调用的那一刻还没有准备好,这就是为什么我的代码有状态的承诺。

EDIT 2:编辑2:

 constructor(props) {
        super(props);
        this.ongoingRequestId = undefined;
        this.ongoingRequests = new Map();
        this.state = {
            servicesList: this.getServicesList(this.getInstanceIds())
        }
    }

Here is my constructor, where I create my this.state.servicesList.这是我的构造函数,我在其中创建了 this.state.servicesList。

Some advice:一些忠告:

  • Do not mix traditional promises syntax with async / await.不要将传统的 promise 语法与 async / await 混用。 It will make your code hard to understand, even for yourself.它会使您的代码难以理解,即使是您自己也是如此。 Do not mix either callback approach with promises.不要将回调方法与承诺混合使用。 Choose one approach and stick to it.选择一种方法并坚持下去。
  • If you are having a hard time with promises, force yourself to use async / await everywhere.如果您在使用 promise 时遇到困难,请强迫自己在任何地方使用 async / await。 async / await is easier to understand in my opinion, because it doesn't break your code flow.我认为 async / await 更容易理解,因为它不会破坏您的代码流。

For instance, transform this:例如,转换这个:

FlowsInventoryAPI.searchServices(/* params */)
  .then((response) => /* response code */)
  .catch((error) => /* error code */)

to:到:

try {
  const response = await FlowsInventoryAPI.searchServices(/* params */);
  /* response code */
} catch (error) {
  /* error code */
}
  • Do not make your constructors asynchronous like you do where you call this.getServicesList , because you cannot wait for an asynchronous operation (like getServicesList ) inside a constructor.不要像调用this.getServicesList那样使构造函数异步,因为您不能在构造函数中等待异步操作(如getServicesList )。 Use instead a static async method.改用静态异步方法。

For instance, transform this:例如,转换这个:

class SomeObject extends Something {
  constructor(props) {
    super(props);
    this.ongoingRequestId = undefined;
    this.ongoingRequests = new Map();
    this.state = {
      servicesList: this.getServicesList(this.getInstanceIds())
    }
  }
}

to:到:

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;
  }
}

Instead of calling const object = new SomeObject(props);而不是调用const object = new SomeObject(props); , do const object = await SomeObject.create(props); , 做const object = await SomeObject.create(props);

You will need to use await keyword to wait for a promise response before continuing.在继续之前,您需要使用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);

Read more about the await keyword 阅读有关await关键字的更多信息

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM