【问题标题】:NodeJS / request promise : the promise is resolved automaticallyNodeJS / 请求承诺:承诺自动解决
【发布时间】:2017-08-02 04:16:25
【问题描述】:

我使用request-promise节点模块如下:

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

我有以下承诺链:

getData().then( data => {
  return getUser(data);
})
.then( data => {
  return getProfiles(data);
}).then( data => {
  updateAddresses(data);
});

updateAddresses 如下:

function updateAddresses(data){
   var promises = data.map( (aProfile) => {
      var options = {url:'http://example.com', method:'POST'};
      return rp(options);
   });

   // Promise.all(promises).then(...);
}

所以我正在为数组的每个元素准备一个承诺(request-promise)。

问题是即使我删除了Promise.all,这些承诺也会触发!

这怎么可能?我怎样才能保证不触发?

问候。

【问题讨论】:

  • return Promise.all() in updateAddresses
  • 我不确定我是否很好地解释了这个问题:在我使用Promise.all 之前,我想按原样检查代码。我注意到承诺正在得到解决。我只想将它们存储在 promises 数组中。
  • 然后存储选项,在你准备好之前不要调用rp。你仍然需要从updateAddresses 返回一些东西,否则你的map() 将在作用域结束时丢失。
  • 您能否发布一些关于如何存储选项并在他们的承诺上应用 Promise.all 的代码 sn-p ?
  • 当然有。 Promise.all 只是一个等待多个承诺的辅助函数。 Promise 是结果值,而不是要执行的操作。当您调用 rp 时会触发请求 - 而不是在您调用 then 时触发。

标签: node.js promise request request-promise


【解决方案1】:

您的updateAddresses 没有返回任何可以调用then() 的内容,您也没有等待updateAddress 的结果。

function updateAddresses(data){
   var promises = data.map( (aProfile) => {
      var options = {url:'http://example.com', method:'POST'};
      return rp(options);
   });

   //Return something to then()
   return Promise.all(promises).then(...);
}

那就等着吧:

getData().then( data => {
  return getUser(data);
})
.then( data => {
  return getProfiles(data);
}).then( data => {
  return updateAddresses(data);
}).then(e => somethingelse);

根据您的要求存储mapped 地址对象:

function updateAddresses(data) {
    return data.map((aProfile) => {
        return {
            url: 'http://example.com',
            method: 'POST'
        }
    });
}

getData()
    .then(data => getUser(data))
    .then(data => getProfiles(data))
    .then((data) => {
        let addressOptions = updateAddresses(data);
        /*
         * You now have an Array of Objects of the form:
         * {
         *     url: "",
         *     method: "",
         * }
         */
        return Promise.resolve(addressOptions);
    })
    .then(addressOptions => Promise.all(addressOptions.map(address => rp(address))))
    .then((arrayOfResolvedData) => {
        /*
         * arrayOfResolvedData is an Array of data per whatever rp() returns
         * probably Response Objects
         */
        console.log(arrayOfResolvedData);
    })

【讨论】:

  • 请对这个问题发表评论:在我运行 Promise.all 代码之前请求被触发。
【解决方案2】:

你可以做 zero298 在他的编辑中建议的。

主要问题是您将数据映射到实际的承诺,而不是准备执行承诺的东西,

比较

Let promises = Options.map(option => execute(option))
Promise.all(promises)

Let promiseGenerators =Options.map(option => () => execute(option))
Promise.all(promiseGenerators.map(generator => generator())

第二次调用将返回承诺的函数,它就会开始执行它。这就是问题所在,因为您调用 rp(options) 太快了。

【讨论】:

    猜你喜欢
    • 2019-09-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-26
    • 1970-01-01
    • 2015-06-24
    • 2022-01-22
    • 1970-01-01
    相关资源
    最近更新 更多