【问题标题】:Promise is returning [object Promise]Promise 正在返回 [object Promise]
【发布时间】:2018-03-25 00:04:35
【问题描述】:

我正在尝试进行基本检查以查看图像是否为视网膜并且具有纵向比例。我的所有检查功能都运行良好。我的问题是,在应该返回我从检查中得到的布尔值的最终函数中,它返回了[object Promise]。我不知道为什么当我解决承诺时这没有返回我的布尔值。

当我运行.then(res => console.log(res)) 时,它会输出我的布尔响应,但返回承诺的函数getImageMeta() 只会返回[object Promise],这让我认为承诺实际上并没有得到解决。

如果我能得到一些帮助,那就太好了!

/************************************
   Check if image is retina portrait
************************************/
const checkIfPortrait = src => !isRetina(src) ? false : getImageMeta(src).then(res => res);
 const isRetina        = src => src.indexOf('@2x') !== -1;
 const isPortrait      = ({ naturalWidth, naturalHeight }) => naturalHeight > naturalWidth ? true : false;

 function getImageMeta (src) {
    const img = new Image();
    img.src = src;

    return new Promise((resolve, reject) => {
      return img.addEventListener("load", function () {
         return resolve(isPortrait(this));
      }, false);
    });
  }


 export { checkIfPortrait }

这就是我调用函数的方式:

<img src={media[i].image} alt={media[i].alt} data-portrait={checkIfPortrait(media[i].image)} />

【问题讨论】:

  • 查看MDN - Using Promises 以了解有关承诺的更多信息。 .then(res =&gt; res) 是多余的,你不需要它。 “我的问题是在最终函数中应该返回布尔值” 这是不可能的。您不能将异步进程转换为同步进程。
  • 当我在异步函数中除了服务调用之外忘记提及“等待”时出现此错误。添加后解决了。

标签: javascript promise


【解决方案1】:

这是预期的结果。当您返回 new Promise 对象时,它始终是一个 Promise 对象(字符串化时为 [object Promise])。

您可以使用.then 方法(或在async 函数中使用await)访问承诺的结果。然后在/如果结果可用时调用您的 .then 回调,这将在您调用 resolve 之后发生,或者如果承诺之前已经解决,它将被相当快地调用。

function getImageMeta(src) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve({metadata: `for: ${src}`});
        }, 100);
    });
}

getImageMeta('test.png').then(meta => {
    console.log(meta); // {"metadata": "for: test.png"}
});

(async () => {
    const meta = await getImageMeta('test.png');
    console.log(meta); // {"metadata": "for: test.png"}
})();

【讨论】:

    【解决方案2】:

    promise 的基本理念是,它可以让您立即返回一些东西,即使它要等到以后才能解决。它代表了它的最终价值。所以getImageMeta () 会立即返回承诺,即使它还没有解决。

    一旦你得到getImageMeta () 返回的promise,你就可以使用它的then() 来等待最终的布尔值,它最早会出现在下一个事件循环周期中。

    使用您当前的代码,您将getImageMeta() 返回的承诺保存到checkIfPortrait。所以现在checkIfPortrait 持有这个承诺,你可以打电话给then()。由于您正在导出 checkIfPortrait,您可能最终会在导入它的模块上调用 then:

     // import checkIfPortrait
    checkIfPortrait(src)
    .then(ret_val => {
       //you can access boolean here in ret_val
    })
    

    【讨论】:

    • 对不起@BradyEdgar - 我知道现在发生了什么。我没有意识到您将结果保存到 checkIfPortrait 并将其导出。 checkIfPortrait 持有对承诺的引用。您将在checkIfPortrait 上致电then()。但是 promise 的工作方式你不能直接访问这个值,因为那还为时过早。需要在then()回调中处理。
    【解决方案3】:

    问题现已解决,感谢大家的帮助。如前所述,问题是我在解决承诺之前调用了承诺的价值,并且在解决后无法更新该价值。

    所以我所做的是确保在运行函数之前可以访问图像数据。然后,一旦我有一个已解决的承诺,它就会更新图像数据以显示它是否是纵向的。

    所以最终的代码是这样的:

    const enhance = lifecycle({
       componentWillMount: function () {
         Object.keys(this.props.media).map((i) =>
           checkIfPortrait(this.props.media[i].image)
             ? this.props.media[i].isPortrait = true
             : this.props.media[i].isPortrait = false
           );
       }
     })
    

    const checkIfPortrait = src => !isRetina(src) ? false : getImageMeta(src).then(res => res);
     const isRetina        = src => src.indexOf('@2x') !== -1;
     const isPortrait      = ({ naturalWidth, naturalHeight }) => naturalHeight > naturalWidth ? true : false;
    
     function getImageMeta (src) {
       const img = new Image();
       img.src = src;
    
       return new Promise((resolve, reject) => {
         return img.addEventListener("load", function () {
           return resolve(isPortrait(this));
         }, false);
       });
     }
    
    
     export { checkIfPortrait }
    

    <img src={media[i].image} alt={media[i].alt} data-portrait={media[i].isPortrait} />
    

    【讨论】:

      【解决方案4】:

      试试这个,

      function axiosTest() {
          axios.get(url)
              .then(response => response.data)
              .catch(error => error);
      }
      
      async function getResponse () {
              const response = await axiosTest();
              console.log(response);
      }
      
      getResponse()
      

      它可以工作,但是您要获取响应的每个函数都需要是异步函数或使用额外的.then() 回调。

      function axiosTest() {
          axios.get(url)
              .then(response => response.data)
              .catch(error => error);
      }
      
      async function getResponse () {
              axiosTest().then(response => {
                      console.log(response)
              });
      }
      
      getResponse()
      

      如果有人知道避免这种情况的方法,请告诉。

      还可以查看 Katsiaryna (Kate) Lupachovaarticle on Dev.to。我认为这会有所帮助。

      【讨论】:

        【解决方案5】:

        你的函数返回承诺,所以你应该把它称为承诺

           <img src={media[i].image} alt={media[i].alt} data-portrait={checkIfPortrait(media[i].image).then(result=>result})};
        

        【讨论】:

          【解决方案6】:

          Promise 返回 [object Promise] 然后它返回一个空值。 检查mongo DB的集合,确保访问路径正确。

          【讨论】:

            猜你喜欢
            • 2021-07-23
            • 1970-01-01
            • 1970-01-01
            • 2021-05-04
            • 2018-11-16
            • 2022-11-14
            • 1970-01-01
            • 2022-08-22
            • 2020-04-03
            相关资源
            最近更新 更多