javascript - 如何使用异步请求构建代码

标签 javascript

我正在寻找一些建议,以了解在混合使用异步请求时如何更好地构建我的代码。以下是对我似乎一直遇到的问题的过度简化。

假设我有一个对象,它具有三个执行操作的方法。我有一个按顺序调用所有三种方法的加载函数。在 partA 完成之前,partB 不应运行,在 partB 完成之前,partC 不应运行。

myObject = {
  load: function() {
    myOjbect.partA();
    myObject.partB();
    myObject.partC();
  }

  partA: function() {
    // Do something here...
  }

  partB: function() {
    // Do something here...
  }

  partC: function() {
    // Do something here...
  }
}

myObject.load();

但是现在有一个新的要求,我需要使用对 API 的异步调用来获取 partA 中的一些数据,例如Google 地点:

partA: function() {
  // Do something asynchronous
  var placesService = new gm.places.PlacesService(map);
  var request = { placeId: 'ABC' };

  placesService.getDetails(request, function(results, status) {
    placeDetails = JSON.stringify(results);
    // Do something with 'results'

    // Then do a few more things...
  });
}

现在,我必须在 API 的回调中包含对 partB 和 partC 的调用。现在我的加载方法只是对 partA 的调用:

myObject = {
  load: function() {
    myOjbect.partA();
  }

  partA: function() {
    // Do something asynchronous
    var placesService = new google.map.places.PlacesService(map);
    var request = { placeId: 'ABC' };

    placesService.getDetails(request, function(results, status) {
      // Do something with 'results'

      // Then do a few more things...

      // Then continue with Parts B and C...
      myObject.partB();
      myObject.partC();
    });
  }

  partB: function() {
    // Do something here...
  }

  partC: function() {
    // Do something here...
  }
}

有没有什么方法可以避免以这种方式重构我的代码,这样我就不会在回调中隐藏方法调用?这是使用 promises 会使代码更清晰的地方吗?

最佳答案

PlacesServicegetDetails 方法仅适用于回调,它不会返回您可以使用 async/await 处理的 promise 。

因此,如果您想避免使用 async/await 嵌套对 partBpartC 的调用,您必须让回调返回一个 promise,如下所示:

// faking the google API for demo
const google = {
  map: {
    places: {
      PlacesService: class {
        getDetails(req, cb) {
          cb("RESULTS", "STATUS");
        }
      }
    }
  }
};
const map = "map";

const myObject = {
  load() {
    myObject.partA();
  },

  async partA() {
    // Do something asynchronous
    console.log("partA");
    var placesService = new google.map.places.PlacesService(map);
    var request = { placeId: "ABC" };

    const { results, status } = await new Promise(resolve =>
      placesService.getDetails(
          request,
          // pass a callback to getDetails that resolves the promise
          (results, status) => resolve({ results, status })
      )
    );
    this.partB(results, status);
    this.partC(results, status);
  },

  partB(results, status) {
    // Do something here...
    console.log("partB", results, status);
  },

  partC(results, status) {
    // Do something here...
    console.log("partC", results, status);
  }
};

myObject.load();

关于javascript - 如何使用异步请求构建代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54117905/

相关文章:

javascript - ReactJS/Django 如何将搜索字符串编码到 onClick 按钮中以重定向到确切的 URL?

javascript - 如何使用 d3.js 创建像 StackOverflow 信誉图这样的图表?

javascript - 单击更改动态按钮的 CSS

javascript - 加载 JavaScript 文件 - 条件串联

javascript - HTML 中是否可以使 IE 更宽容标记错误(例如无关标签)?

javascript - 如何在 Ipython 笔记本中添加外部 javascript 文件

java - YUI 压缩器与 Granule

javascript - (React Native) 显示数组中项目的卡片列表

javascript - jsplumb 连接不工作

javascript - 当我的 Action 中的函数被调用时,除非我取出调度,否则它不会工作