2017-10-12 224 views
1

我想做一個基本的檢查,看看圖像是視網膜,並有肖像比例。我有所有檢查功能工作得很好。我的問題是,在最終的函數,應該返回我從我的支票得到的布爾值,它返回[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)} /> 
+0

看一看[MDN - 使用承諾(https://developer.mozilla.org/ en-US/docs/Web/JavaScript/Guide/Using_promises)瞭解有關承諾的更多信息。 '。那麼(res => res)'是多餘的,你不需要它。 *「我的問題是,在應該返回布爾值的最終函數中」*這是不可能的。您不能將異步進程轉換爲同步進程。 –

回答

7

這是預期的結果。當您返回一個new Promise對象時,它始終是承諾對象([object Promise])。

您可以通過使用.then方法(或在async函數中使用await)來訪問承諾的結果。您的.then回調將在/如果結果可用時調用,這將在您致電resolve後發生,或者如果承諾已經解決,然後它將被調用,而且會很快被調用。

1

承諾的基本思想是它可以讓你馬上返回一些東西,即使它晚些時候纔會解決。它代表了它的最終價值。所以getImageMeta()立即返回承諾,即使它還沒有解決。

一旦你得到了getImageMeta()返回的承諾,你可以使用它的then()來等待最後的布爾值,這個布爾值最早會出現在下一個事件循環週期中。

使用您當前的代碼,您可以將由getImageMeta()返回的承諾保存到checkIfPortrait。所以現在checkIfPortrait持有這個承諾,你可以打電話then()就可以了。既然要導出checkIfPortrait你最終可能會認爲它導入模塊上調用,則:

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

對不起@BradyEdgar - 我看到現在發生了什麼。我沒有意識到你保存的結果checkIfPortrait和出口。 checkIfPortrait帶有對承諾的引用。你會在'checkIfPortrait'上調用'then()'。但承諾的方式工作,你不能直接訪問價值,因爲這將是太快。你需要在'then()'回調中處理它。 –

0

現在的問題是解決了,感謝大家的幫助。就像所說的那樣,問題在於我在承諾的價值能夠得到解決之前稱之爲承諾的價值,並且在解決問題後無法更新該價值。

因此,我所做的是在運行該功能之前確保圖像數據是可訪問的。然後,一旦我有了解決的承諾,它就會更新圖像數據以顯示它是否是人像。

所以最終的代碼如下所示:

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