【问题标题】:how to send response only when a function is complete using promises如何仅在使用 Promise 完成功能时发送响应
【发布时间】:2018-05-12 23:30:31
【问题描述】:

如何仅在特定功能完成时发送响应。我尝试为此使用承诺,但这似乎不起作用。

let dealPromise = new Promise(function(resolve, reject){
for (let  i = 0;i < deals.length;i++) {
  let link = 'https://api.cortellis.com/api-ws/ws/rs/deals-v2/deal/' + deals[i] + '?fmt=json';
  let options = {
    method: 'GET',
    uri: link,
    auth: auth,
  };
  let constant = constants.collection('clarivate');

  request(options, function(error, response, body) {
    body = JSON.parse(body).dealRecordOutput;
    if (body.length === 0) {
      res.status(204).json({'data': []});
      next();
    }
    else {
      let type = body.Type;
      type_list.push(type);
      let status_val = body.Status;
      status_list.push(status_val);

      resp['type'] = type_list;
      resp['status'] = status_list;

       }
      });
    }
    resolve(resp);
  });

  dealPromise.then(function (result) {
    res.status(200).json({'data': result});
  });

还有其他方法可以解决这个问题吗?

【问题讨论】:

  • 神秘的resp声明在哪里?
  • type_liststatus_list
  • 您的代码并未真正显示您想要的功能。开放式问题。当您在迭代过程中收到body.length === 0 时,您希望发生什么?仅供参考,在您发送回复后致电next() 也绝不是您想要做的。你想用type_liststatus_listresp 做什么? result 是什么?我有一个新的结构来做这个,主要是书面的,但是没有这些答案,我不能发布对你有用的东西。

标签: node.js promise


【解决方案1】:

您正在使用 for 执行多个请求,即使您的承诺得到解决,这些请求也会得到解决。

我会这样做:

const myPromises = Promise.all(deals.map(deal => {
    return new Promise((resolve, reject) => {
        // ... do your request here
        // call resolve in the callback request 
    })
}))

myPromises.then(result => {
    // ... here all your requests have been resolved
    // call res.status(200).json({...})
})

【讨论】:

  • new Promise(...) 可以(并且应该)完全避免。 [request-promise](https://www.npmjs.com/package/request-promise),将允许 return request(...).then(...) 在 .map 回调中。
  • 是的,我们知道,我只是在尝试使用已经编写的代码,这样更容易理解 Promises.all 背后的想法。
【解决方案2】:

如果您切换到 request-promise 库来执行您的请求,那么它将为每个请求返回一个承诺,然后您可以使用 Promise.all() 知道它们何时完成。

您的代码在一些主题上有些不完整,例如遇到空主体时该怎么办以及您希望如何构建最终的result 数据。因此,允许您填写这些详细信息,这里有一个适合您的通用结构:

const rp = require('request-promise');

let type_list = [], status_list = [];
Promise.all(deals.map(item => {
    let options = {
        method: 'GET',
        uri: 'https://api.cortellis.com/api-ws/ws/rs/deals-v2/deal/' + item + '?fmt=json',
        auth: auth
    };
    let constant = constants.collection('clarivate');
    return rp(options).then(body => {
        if (body.length !== 0) {
            try {
                let data = JSON.parse(body).dealRecordOutput;
                type_list.push(data.Type);
                status_list.push(data.Status)
            } catch(e) {
                // log and skip items with bad JSON
                console.log(e);
            }
        }
    });
})).then(() => {
    // all requests done here
    let result = {};
    // put code here to create result using type_list and status_list
    res.status(200).json({data: result});
}).catch(err => {
    // got an error in one of the requests
    console.log(err);
    res.sendStatus(500);
});

【讨论】:

    猜你喜欢
    • 2018-05-31
    • 1970-01-01
    • 2015-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-16
    • 2014-02-12
    相关资源
    最近更新 更多