简体   繁体   English

JS承诺在函数之间传递/等待承诺

[英]JS promise passing between functions / wait for promises

I am trying to work through JS Promises in node.js and don't get the solution for passing promises between different function. 我正在尝试通过node.js中的JS Promises进行操作,而没有获得在不同功能之间传递Promise的解决方案。

The task 任务

For a main logic, I need to get a json object of items from a REST API. 对于主要逻辑,我需要从REST API获取项目的json对象。 The API handling itself is located in a api.js file. API处理本身位于api.js文件中。

The request to the API inthere is made through the request-promise module. 通过request-promise模块向其中的API发出请求 I have a private makeRequest function and public helper functions, like API.getItems() . 我有一个私有的makeRequest函数和一个公共帮助器函数,例如API.getItems()

The main logic in index.js needs to wait for the API function until it can be executed. index.js的主要逻辑需要等待API函数才能执行。

Questions 问题

  1. The promise passing kind of works, but I am not sure if this is more than a coincidence. 诺言已经过时了,但是我不确定这是否仅仅是巧合。 Is it correct to return a Promise which returns the responses in makeRequest ? 返回在makeRequest返回响应的Promise是否正确?
  2. Do I really need all the promises to make the main logic work only after waiting for the items to be setup? 我是否真的需要所有承诺才能使主要逻辑仅在等待设置项目后才起作用? Is there a simpler way? 有没有更简单的方法?
  3. I still need to figure out, how to best handle errors from a) the makeRequest and b) the getItems functions. 我仍然需要弄清楚如何最好地处理a) makeRequest和b) getItems函数中的错误。 What's the best practice with Promises therefor? Promises的最佳实践是什么? Passing Error objects? 传递错误对象?

Here is the Code that I came up with right now: 这是我现在想出的代码:

// index.js

var API    = require('./lib/api');

var items;

function mainLogic() {

  if (items instanceof Error) {
    console.log("No items present. Stopping main logic.");
    return;
  }

  // ... do something with items
}


API.getItems().then(function (response) {
  if (response) {
    console.log(response);
    items = response;
    mainLogic();
  }
}, function (err) {
  console.log(err);
});

api.js api.js

// ./lib/api.js

var request = require('request-promise');

// constructor
var API = function () {
  var api = this;

  api.endpoint = "https://api.example.com/v1";
  //...
};

API.prototype.getItems = function () {
  var api      = this;
  var endpoint = '/items';


  return new Promise(function (resolve, reject) {
    var request = makeRequest(api, endpoint).then(function (response) {
      if (200 === response.statusCode) {
        resolve(response.body.items);
      }
    }, function (err) {
      reject(false);
    });
  });
};

function makeRequest(api, endpoint) {
  var url     = api.endpoint + endpoint;
  var options = {
    method: 'GET',
    uri: url,
    body: {},
    headers: {},
    simple: false,
    resolveWithFullResponse: true,
    json: true
  };

  return request(options)
    .then(function (response) {
      console.log(response.body);
      return response;
    })
    .catch(function (err) {
      return Error(err);
    });
}

module.exports = new API();

Some more background: At first I started to make API request with the request module, that works with callbacks. 更多背景知识:最初,我开始使用与回调一起使用的request模块发出API请求。 Since these were called async, the items never made it to the main logic and I used to handle it with Promises. 由于这些被称为异步,因此这些项从未进入主要逻辑,而我过去常常通过Promises处理它。

You are missing two things here: 您在这里缺少两件事:

  1. That you can chain promises directly and 您可以直接链接诺言,
  2. the way promise error handling works. 许诺错误处理的工作方式。

You can change the return statement in makeRequest() to: 您可以将makeRequest()的return语句更改为:

return request(options);

Since makeRequest() returns a promise, you can reuse it in getItems() and you don't have to create a new promise explicitly. 由于makeRequest()返回了一个makeRequest() ,因此您可以在getItems()重用它,而不必显式创建一个新的Promise。 The .then() function already does this for you: .then()函数已经为您做到了:

return makeRequest(api, endpoint)
    .then(function (response) {
        if (200 === response.statusCode) {
            return response.body.items;
        }
        else {
            // throw an exception or call Promise.reject() with a proper error
        }
    });

If the promise returned by makeRequest() was rejected and you don't handle rejection -- like in the above code --, the promise returned by .then() will also be rejected. 如果makeRequest()返回的promise被拒绝了,而您没有像上面的代码那样处理拒绝,那么.then()返回的promise也将被拒绝。 You can compare the behaviour to exceptions. 您可以将行为与异常进行比较。 If you don't catch one, it bubbles up the callstack. 如果您没有抓住,它将使调用栈冒泡。

Finally, in index.js you should use getItems() like this: 最后,在index.js您应该像这样使用getItems()

API.getItems().then(function (response) {
  // Here you are sure that everything worked. No additional checks required.
  // Whatever you want to do with the response, do it here.
  // Don't assign response to another variable outside of this scope.
  // If processing the response is complex, rather pass it to another 
  // function directly.
}, function (err) {
  // handle the error
});

I recommend this blog post to better understand the concept of promises: 我推荐这篇博客文章,以更好地理解promise的概念:

https://blog.domenic.me/youre-missing-the-point-of-promises/ https://blog.domenic.me/youre-missing-the-point-of-promises/

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

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