将 Promise 用于 onload 和 onerror 后返回状态值
Returning status values after using Promise for onload and onerror
我正在尝试使用 javascript onload 和 onerror 查看 page/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', size, {
'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"))
我猜你可能对 promises 有点陌生,这表明你已经阅读了建议的副本,但你可以按照以下方式重新制定你的代码
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') );
这将使用 resolve(成功)和 reject(失败)来使用 promise 工作的正常流程。
通过返回承诺,任何消费者都可以使用 then
或 catch
链来处理成功或失败
假设你想在一个函数中使用上面的代码,然后它改变了一点,你不能真正同步地检查这个,除非调用者是一个 async
函数,在这种情况下你可以这样做喜欢:
const validateInput = async () => {
let isValidImage = false;
try {
isValidImage = await isImgUrlValid( path );
} catch (ex) {
// not a correct image
}
};
但这对你没有帮助,因为现在 validateInput
隐含地 returns 一个承诺,所以你必须把这个作为一个承诺来处理。
您应该 return 您创建的承诺从 isImgURlValid
返回给调用者。然后,调用者可以等待 promise 解析并使用解析后的值来查看提供的图像源是否有效。
这里是受问题代码启发的例子。您可以在输入框中输入图片来源,然后按回车触发事件。
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" />
我正在尝试使用 javascript onload 和 onerror 查看 page/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', size, {
'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"))
我猜你可能对 promises 有点陌生,这表明你已经阅读了建议的副本,但你可以按照以下方式重新制定你的代码
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') );
这将使用 resolve(成功)和 reject(失败)来使用 promise 工作的正常流程。
通过返回承诺,任何消费者都可以使用 then
或 catch
链来处理成功或失败
假设你想在一个函数中使用上面的代码,然后它改变了一点,你不能真正同步地检查这个,除非调用者是一个 async
函数,在这种情况下你可以这样做喜欢:
const validateInput = async () => {
let isValidImage = false;
try {
isValidImage = await isImgUrlValid( path );
} catch (ex) {
// not a correct image
}
};
但这对你没有帮助,因为现在 validateInput
隐含地 returns 一个承诺,所以你必须把这个作为一个承诺来处理。
您应该 return 您创建的承诺从 isImgURlValid
返回给调用者。然后,调用者可以等待 promise 解析并使用解析后的值来查看提供的图像源是否有效。
这里是受问题代码启发的例子。您可以在输入框中输入图片来源,然后按回车触发事件。
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" />