簡體   English   中英

在 TS 中使用 Promise 從其加載 function 獲取圖像寬度失敗

[英]Failed getting Image width from its onload function using Promise in TS

我使用以下代碼:

import React, { Component } from 'react';
import { render } from 'react-dom';

  const imageString = 'https://glebekitchen.com/wp-content/uploads/2018/09/neapolitanpepperoni.jpg';

  function getPromise(imageData) {
    return new Promise((resolve, reject) => {
        const myImage = new Image();
        myImage.onload = () => resolve(myImage.width);
        myImage.onerror = reject(-1);
        myImage.src = imageData; 
      });
  }

  async function getWidth() {
    const promise = await getPromise(imageString);
    promise.then(width => {
        return width;
      }).catch(ex => {
            return -1;
      });
  }
  
class App extends Component<AppProps, AppState> { 
  render() {
    const a = getWidth(); 
    debugger;
    return (
      <div>
        <p>
          {a};
        </p>
      </div>
    );
  }
}

render(<App />, document.getElementById('root'));

(也將其加載到: https://stackblitz.com/edit/react-ts-a7ugfq?file=index.tsx

雖然期望使用 getWidth function 獲得寬度 - 我只得到 promise 的寬度作為它的 PromiseResult 我做錯了什么? 使用上述 promise 時,如何獲得特定值而不是 object?

提前致謝

getWidth有問題。 您正在等待getPromise的結果。 這意味着 function 的結果不再是 Promise,而是解析語句中返回的值。 因此thencatch方法將不起作用。 相反,只需從getPromise返回結果

async function getWidth() {
  return getPromise(imageString);
}

不要在render方法中使用副作用操作。 此方法應該做一件事,使用可用數據渲染 HTML,但不進行任何計算或從異步函數獲取數據。

為此,您擁有componentDidMount生命周期方法,該方法在組件首次呈現時運行。

在這個方法中,調用getWidth function 並從中獲取圖像的寬度。 從這里你應該更新一個 state 這將使組件知道它的數據已經改變並且應該重新渲染組件。

class App extends Component<AppProps, AppState> {
  constructor(props) {
    super(props);

    this.state = {
      imageWidth: null // Set a initial state of null.
    }
  }

  componentDidMount() {
    getWidth().then(width => {
      this.setState({
        imageWidth: width
      });
    });
  }

  render() {
    const imageWidth = this.state.imageWidth;
    
    // If the width is not yet set, render nothing.
    if (imageWidth === null) {
      return null;
    }

    return (
      <div>
        <p>
          {a};
        </p>
      </div>
    );
  }
}

Promise 是異步的,所以你必須“等待”它們。 有2種方式。

  1. 使用異步渲染等待結果 function
  2. 等待 promise,設置變量為 state,讓 React 重新渲染組件。

使用異步渲染 function

class App extends Component<AppProps, AppState> { 
  async render() {
    const a = await getWidth(); 
    debugger;
    return (
      <div>
        <p>
          {a};
        </p>
      </div>
    );
  }
}

使用 state。 當心,有一個缺點。

class App extends Component<AppProps, AppState> { 
  
  render() {
    const [a, setA] = useState(null);
    getWidth().then(width => setA(width)); 
    debugger;
    return (
      <div>
        <p>
          {a};
        </p>
      </div>
    );
  }
}

使用這種 state 方法的“缺點”是,第一次渲染組件時,組件使用null作為a的值。 最好的一點是,即使您的異步方法的值尚不存在,您的應用程序也會呈現。 你可以添加一些loading特性,或者你可以return null告訴 React 你根本不想渲染這個組件。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM