【问题标题】:How to run a callback function before the function end in JS? [duplicate]JS中函数结束前如何运行回调函数? [复制]
【发布时间】:2021-04-06 10:12:23
【问题描述】:

我希望在函数结束之前运行一个回调函数。但是,回调似乎是异步的,我正在构建的数组最终是未定义的。下面是代码:

  function getLocDetails(location) {
    const google = window.google
    const service = new google.maps.places.PlacesService(mapRef.current)

    var request = {
      placeId: location.place_id
    }

    function callback(place, status) {
      if (status === google.maps.places.PlacesServiceStatus.OK) {
        // console.log(place)
        return place
      }
    }

    let tempDetailedPlace = service.getDetails(request, callback)
    console.log(tempDetailedPlace)
    return tempDetailedPlace
  }

tempDetailedPlace 始终返回未定义。我已经检查以确保 google-maps-api 是正确的,并且我在其他地方使用了相同的功能(它工作正常)。有什么方法可以使回调同步或使其在 return 语句之前暂停?还是我需要实现某种异步功能?谢谢!

【问题讨论】:

  • 使用承诺、异步、等待
  • 在第一个函数完成之前,您无法开始处理第二个函数。 JavaScript 是同步的。
  • @ScottMarcus - 虽然是真的,但 OP 的问题确实是关于异步行为的,并且在问题中说明了很多。 John 是正确的,应该使用 async/await 编写答案,这样 OP 才能从中受益。
  • @RandyCasburn OP 声明为问题的标题和第一行我希望在函数结束之前运行一个回调函数。,因此我的回应。跨度>
  • @ScottMarcus - 很公平。

标签: javascript reactjs asynchronous google-maps-api-3


【解决方案1】:

service.getDetails 必须返回一个承诺,因此您需要在调用后添加一个 .then() 块 比如,

service.getDetails(request).then(callback)

假设您希望在收到响应后调用您的回调函数。

或者使这个函数异步并在调用之前添加等待以等待异步任务完成。

【讨论】:

    【解决方案2】:

    在这种情况下,回调函数中的return 语句被吞下,不会为您做任何事情。因为,正如您所认识到的,这里涉及到一些异步活动,所以必须区别对待此代码。

    现代方法是使用Async/Await

    以下代码演示了这种方法。

    几点说明:

    1. 注意asyncawait的使用
    2. callback() 方法不再有返回值,而是设置属性值
    3. service.getDetails() 的调用是异步的 - 这是您寻求的解决方案
    4. 现在返回异步值的结果

    最后,最后一行告诉你如何调用getLocDetails()

    该函数的返回是一个 Promise 对象,您可以使用 .then() 来处理返回的异步结果。

    async function getLocDetails(location) {
      const google = window.google
      const service = new google.maps.places.PlacesService(mapRef.current)
      let processedOutput;
    
      var request = {
        placeId: location.place_id
      }
    
      function callback(place, status) {
        if (status === google.maps.places.PlacesServiceStatus.OK) {
          // console.log(place)
          processedOutput = 'something you want this to be';
        }
      }
    
      await service.getDetails(request, callback);
      return processedOutput;
    }
    
    getLocDetails(someLocation).then(output => { console.log(output); });

    【讨论】:

    • 非常感谢您的回复。我已经尝试过这个版本的 async/await,但输出似乎仍然未定义。我在名为getPlacesDetailes 的同步函数中调用异步getLocDetails。这会影响异步生命周期吗?
    • 不,不会有不良影响。但是,请确保您仅在 .then(/* output can only be used here */ ) 中使用来自 getLocDetails() 的输出。您不能将输出分配给 then 之外的变量 - 这将产生 undefined
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-05
    • 2018-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多