代码之家  ›  专栏  ›  技术社区  ›  lightyrs

如何包装异步包函数?

  •  0
  • lightyrs  · 技术社区  · 8 年前

    我正在使用流行的节点库, got ,简单地说 GET 对JSON API的请求。

    我有一个抽象请求的函数,如下所示:

    function performRequest(url) {
      got(url, {
        json: true
      }).then(function (response) {
        return formatResponse(response.body);
      }).catch(function (error) {
        console.log(error.response.body);
      });
    }
    

    formatResponse 是一个简单的同步方法,用于修改从API返回的JSON。

    我想打电话 performRequest 然后使用返回值(一旦解析)。目前 性能要求 未被识别为异步方法,我的代码正在调用它,然后立即继续。

    function myBigFunction() {
      var url = composeUrl();
      var res = performRequest(url);
    
      doMoreStuffWithResponse(res);
    }
    

    我知道我需要利用 Promise 然而,我始终不清楚如何将Promise与已经使用Promise的内置库函数结合使用(如本例)。

    我也完全接受这样一种可能性,那就是我在这件事上完全错了。在这种情况下,我会感激一些重定向。

    谢谢你抽出时间。

    2 回复  |  直到 8 年前
        1
  •  3
  •   Jared Smith    8 年前

    明白什么是承诺吗 它是 价值 ,你可以这样对待它。为了“读取”值,您将函数传递给Promise的 then 方法你不需要 myBigFunction .在Promise解析后,您想要运行的任何内容只需要传递给 然后 :

    var req = performRequest(composeURL());
    req.then(doStuffWithResponse);
    

    现在,我并不特别喜欢这种方式,尽管我经常这样做。我更喜欢具有以下功能: 承诺并援引其 然后 方法:

    var takesAPromise = function(p) {
      return p.then(/* does stuff */);
    };
    

    请注意,它返回已完成任务的承诺。但我更喜欢的是ES6 one liner:

    let wrap = f => p => p.then(val => f.call(null, val));
    

    现在,您可以包装任意函数,将Promise作为输入,并将其作为输出返回。如果承诺是一个单子,这将是他们的 bind 作用让它与任意算术的函数无缝地工作是留给读者的练习。

        2
  •  1
  •   Bergi    8 年前

    你总是想 return 职能部门的承诺:

    function performRequest(url) {
      return got(url, {
    //^^^^^^
        json: true
      }).then(function(response) {
        return formatResponse(response.body);
      }, function(error) {
        throw new Error(error.response.body);
      });
    }
    

    这样,您可以使用另一个函数在大函数中等待结果 then :

    function myBigFunction() {
      var url = composeUrl();
      var promise = performRequest(url);
      return promise.then(function(res) {
        return doMoreStuffWithResponse(res);
      });
    }
    

    简而言之

    function myBigFunction() {
      return performRequest(composeUrl()).then(doMoreStuffWithResponse);
    }
    

    所以你可以这样称呼它

    myBigFunction().catch(function(error) {
      console.log(error.message);
    });