Javascript 使用TS中的Promise从其onload函数获取图像宽度失败
我使用以下代码:Javascript 使用TS中的Promise从其onload函数获取图像宽度失败,javascript,reactjs,ecmascript-6,promise,Javascript,Reactjs,Ecmascript 6,Promise,我使用以下代码: 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((r
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'));
import React,{Component}来自'React';
从'react dom'导入{render};
常量imageString=https://glebekitchen.com/wp-content/uploads/2018/09/neapolitanpepperoni.jpg';
函数getPromise(imageData){
返回新承诺((解决、拒绝)=>{
const myImage=新图像();
myImage.onload=()=>resolve(myImage.width);
myImage.onerror=拒绝(-1);
myImage.src=图像数据;
});
}
异步函数getWidth(){
const promise=wait getPromise(imageString);
承诺。然后(宽度=>{
返回宽度;
}).catch(ex=>{
返回-1;
});
}
类应用程序(扩展组件)
虽然希望使用getWidth函数获得宽度,但我只获得宽度作为PromiserResult的承诺
我做错了什么?使用上述承诺时,我如何获得特定值而不是对象
提前感谢承诺是异步的,因此您必须“等待”它们。有两种方法
使用异步渲染函数等待结果
等待承诺,将变量设置为state,然后让React重新呈现组件
使用异步渲染函数
class App extends Component<AppProps, AppState> {
async render() {
const a = await getWidth();
debugger;
return (
<div>
<p>
{a};
</p>
</div>
);
}
}
类应用程序扩展组件{
异步呈现(){
常数a=等待getWidth();
调试器;
返回(
{a} );
);
}
}
使用状态。小心,这是不利的
class App extends Component<AppProps, AppState> {
render() {
const [a, setA] = useState(null);
getWidth().then(width => setA(width));
debugger;
return (
<div>
<p>
{a};
</p>
</div>
);
}
}
类应用程序扩展组件{
render(){
const[a,setA]=useState(null);
getWidth()。然后(width=>setA(width));
调试器;
返回(
{a} );
);
}
}
使用此状态方法的“缺点”是,第一次呈现组件时,组件使用null
作为a
的值。
最好的一点是,即使异步方法的值还不存在,应用程序也会呈现。您可以添加一些加载
功能,或者返回null
告诉React您根本不想渲染此组件。getWidth
有问题。您正在等待来自getPromise
的结果。这意味着该函数的结果不再是承诺,而是在resolve语句中返回的值。因此,then
和catch
方法将不起作用。相反,只需从getPromise
async function getWidth() {
return getPromise(imageString);
}
不要在render
方法中使用副作用操作。这个方法应该做一件事,使用可用的数据来呈现HTML,但不做任何计算或从异步函数获取数据
为此,您可以使用componentDidMount
生命周期方法,该方法在组件第一次呈现时运行
在这个方法中,调用getWidth
函数并从中获取图像的宽度。从这里,您应该更新一个状态,该状态将让组件知道其数据已更改,并且应该重新提交组件
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>
);
}
}
类应用程序扩展组件{
建造师(道具){
超级(道具);
此.state={
imageWidth:null//将初始状态设置为null。
}
}
componentDidMount(){
getWidth()。然后(宽度=>{
这是我的国家({
图像宽度:宽度
});
});
}
render(){
const imageWidth=this.state.imageWidth;
//如果尚未设置宽度,则不渲染任何内容。
如果(imageWidth==null){
返回null;
}
返回(
{a} );
);
}
}
您的代码中有很多错误。在getWidth
函数中查看此try catch
块是不必要的;错误处理代码应位于调用代码中。更不用说从catch
块返回错误将隐式地将承诺拒绝转换为承诺履行,从而在调用代码中调用履行处理程序。您可以在一行中重新编写getWidth
函数:返回getPromise(imageString)代码>@Yousaf,我不确定情况是否如此。谢谢你澄清这一点。修改了答案。如果您对更多详细信息感兴趣,请参阅: