我在正确计时 2 个异步操作时遇到问题,因此外部函数在继续之前等待内部函数完成。我正在尝试实施的解决方案基于使用 ES2015 的现有解决方案,因此我无法使用 await 而必须使用 Promises。
该解决方案分为多个类,为了便于概述,我将其称为 Main、Invoker 和 Inner。所以 Main 类使用 Invoker 的一个实例异步执行来自 Inner 类的命令,然后应该等待响应,这有效但它不等待来自 setSize() 的异步 Image.onload()内部类。
class Inner extends Component{
setSize(size){
const newImage = { url: null, imageName: canvasImage.imageName};
... some stuff...
const tempImage = new Image();
tempImage.src = canvas.toDataURL();
tempImage.onload = function(){
... some stuff...
const tempCanvas = document.createElement("canvas");
const tempCtx = tempCanvas.getContext("2d");
tempCtx.drawImage(image, x, y, xa, ya);
newImage.url = tempCanvas.toDataURL();
}
return Promise.resolve(newImage);
}
}
class Main{
resize(size){
imageData = this.execute(commandName,'setSize', size);
imageData.then(image => {
... do stuff with image data...
});
}
execute(commandName, ...args) {
return this._invoker.execute(commandName, ...args);
}
}
class Invoker{
execute(...args) {
let [command] = args;
if (isString(command)) {
command = commandFactory.create(...args);
}
return this._invokeExecution(command).then((value) => {
this.clearRedoStack();
return value;
});
}
}
我已经尝试在 onload 函数内的 setSize 函数中移动“return Promise.resolve(newImage)”,但随后我在调用程序中遇到错误,因为缺少解析。 有什么想法吗?
答案 0 :(得分:3)
你需要返回一个 promise 并在 onload 中解决它。
setSize () {
return new Promise((resolve, reject) => {
...
tempImage.onload = function () {
...
resolve(newimage)
}
})
}
答案 1 :(得分:3)
由于 setSize
函数使用基于回调的语法和 onload
,您需要等到 onload 函数被浏览器调用,
您可以从 setSize
返回一个 promise 并处理 onload
的 resolve
和 onerror
的 reject
,例如:
setSize(size){
return new Promise((res, rej) => {
const newImage = { url: null, imageName: canvasImage.imageName};
... some stuff...
const tempImage = new Image();
tempImage.src = canvas.toDataURL();
tempImage.onload = function(){
... some stuff...
const tempCanvas = document.createElement("canvas");
const tempCtx = tempCanvas.getContext("2d");
tempCtx.drawImage(image, x, y, xa, ya);
newImage.url = tempCanvas.toDataURL();
res(newImage);
}
tempImage.onerror = function(error) {
rej(error)
}
})
}