javascript - JS Promise 在函数之间传递/等待 Promise

标签 javascript node.js promise ecmascript-6

我正在尝试在 Node.js 中处理 JS Promise,但没有找到在不同函数之间传递 Promise 的解决方案。

任务

对于主要逻辑,我需要从 REST API 获取 items 的 json 对象。 API 处理本身位于 api.js 文件中。

对其中API的请求是通过request-promise发出的模块。我有一个私有(private) makeRequest 函数和公共(public)辅助函数,例如 API.getItems()

index.js中的主要逻辑需要等待API函数才能执行。

问题

  1. promise 传递确实有效,但我不确定这是否不仅仅是巧合。返回一个返回 makeRequest 中响应的 Promise 是否正确?
  2. 我真的需要所有 promise 才能使主要逻辑仅在等待项目设置后才起作用吗?有没有更简单的方法?
  3. 我仍然需要弄清楚如何最好地处理来自 a) makeRequest 和 b) getItems 函数的错误。 Promise 的最佳实践是什么?传递错误对象?

这是我现在想出的代码:

// 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

// ./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();

更多背景: 首先我开始使用 request 发出 API 请求模块,与回调一起使用。由于这些被称为异步,因此这些项目从未进入主逻辑,我过去常常使用 Promises 来处理它。

最佳答案

你在这里遗漏了两件事:

  1. 您可以直接链接 promise 并且
  2. Promise 错误处理的工作方式。

您可以将 makeRequest() 中的 return 语句更改为:

return request(options);

由于 makeRequest() 返回一个 Promise,因此您可以在 getItems() 中重用它,而不必显式创建新的 Promise。 .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
        }
    });

如果 makeRequest() 返回的 Promise 被拒绝,并且您不处理拒绝(如上面的代码所示),则 .then() 返回的 Promise 也将被拒绝。您可以将该行为与异常进行比较。如果你没有捕捉到,它就会在调用堆栈中冒泡。

最后,在 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
});

我推荐这篇博文,以更好地理解 promise 的概念:

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

关于javascript - JS Promise 在函数之间传递/等待 Promise,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34674926/

相关文章:

javascript - 如何将两个div的高度锁定在一起?

mysql - 在 Node 循环中插入和选择不起作用

node.js - 即使在设置代理后,npm install express --save 命令也会给出 403 禁止错误

javascript - AngularJS 中 $q 的含义是什么?

javascript - tumblr 主页上的心形(喜欢)按钮

javascript - 如何在表单后缀 '+tag:<keyword>'?

javascript - Node JS 从 axios 返回数据

javascript - 覆盖 getJSON 并获取 jQuery promise (完成/失败)

javascript - 如何查找从服务器运行或不使用javascript的html文件?

node.js - 合并node.js模块导出中的多个回调