问题描述
我正在尝试查看使用javascript onload和onerror是否成功加载页面/ img。我试图读取状态变量,但是当我分配变量以读取状态时却无法读取。 我正在尝试使用可能的答案所提供的承诺,但仍然有些困惑。
const validateInput = (input) => {
const errors = {};
...
if(!(isimgurlValid(input)))
{
errors = `wrong image'`
}
...
return errors;
const isimgurlValid = (path) => {
let img = document.createElement('img');
img.src = path;
let valid
const promise = new Promise(resolve => {
const img = new Image();
img.onload = () => resolve({path,"status": 'ok'});
img.onerror = () => resolve({path,"status": 'error'});
img.src = path;
});
promise.then(function(val) {
console.log(val);
valid = val.status
});
console.log (valid)
}
//when I use async,my render functions no long render the errors properly
export const renderimgurlInput = ({ input,label,type,size,required,Meta: { touched,error } }) => (
<div className={
cs('form-group',{
'has-error': touched && error,'required-input' : required
})
}>
<label className="control-label" htmlFor={input.name}>{label}</label>
<input {...input} placeholder={required ? 'required' : ''} className="form-control" />
{touched && error &&
<span className="help-block">{error}</span>
}
{touched && !error &&
<h1 className="help-block">{error} 'Image worked'</h1>
}
</div>
)
解决方法
const isImgURLValid = (path) => {
return new Promise((resolve,reject) => {
const img = document.createElement("img");
img.src = path;
img.onload = resolve;
img.onerror = reject;
img.src = path;
document.body.appendChild(img);
});
};
isImgURLValid("https://www.gravatar.com/avatar/206601a888686677c4a74c89d9a2920f?s=48&d=identicon&r=PG")
.then(() => console.log("Path is valid"))
.catch(() => console.error("Path isn't valid"))
,
我想您可能对Promise有点陌生,表明您已经阅读了建议的副本,但是您可以通过以下方式重新编写代码
const isImgUrlValid = (path) => {
return new Promise( (resolve,reject) => {
const img = new Image();
img.onload = () => resolve({path,"status": 'ok'});
img.onerror = () => reject({path,"status": 'error'});
img.src = path;
});
};
// when it's found,resolve got called and we know it succeeded
isImgUrlValid('https://www.gravatar.com/avatar/153828e74e3fb5f7aeb19a28a78a378a?s=32&d=identicon&r=PG&f=1').then( status => console.log('image found') );
// when it's not found reject was called,and we need to catch it
isImgUrlValid('invalid_uri').then( _ => console.log('I will never be called') ).catch( err => console.log('no image found') );
然后这将使用“解决”(成功)和“拒绝”(失败)以使用诺言如何正常运行的方式。
通过兑现承诺,任何消费者都可以使用then
或catch
链来成功或失败
假设您要在函数中使用以上代码,那么它会有所变化,您无法真正地进行同步检查,除非调用者是async
函数,在这种情况下,您可以这样做:
const validateInput = async () => {
let isValidImage = false;
try {
isValidImage = await isImgUrlValid( path );
} catch (ex) {
// not a correct image
}
};
但这不能为您提供任何帮助,因为validateInput
隐式返回一个诺言,因此您必须将此诺言作为诺言处理。
您应该将您创建的承诺从isImgURlValid
返回给呼叫者。然后,调用者可以等待promise解析,并使用解析后的值来查看所提供的图像源是否有效。
这是一个受问题代码启发的示例。您可以在输入框中输入图像源,然后按 Enter 触发事件。
const isImgURlValid = (path) => {
return new Promise(resolve => {
const img = new Image()
img.src = path;
img.onload = () => resolve(true);
img.onerror = () => resolve(false);
// img starts loading src when added to the DOM
document.body.append(img);
document.body.removeChild(img);
});
};
const validateInput = async (input) => {
const errors = {};
if (!await isImgURlValid(input)) {
errors.url = "invalid";
}
return errors;
};
document.getElementById("input").addEventListener("change",({target}) => {
validateInput(target.value).then(console.log);
});
<input id="input" type="text" />