我有一个带有方法的类...其中一个实际上包含获取以获取svg文件的方法。那里什么都没有。 问题实际上不在于类,而是在使用时。
我有一个方法getDataFromFile(url),我将它传递给我的SVG url,它可以完成很多工作。问题是...当我使用它时,如果我紧随其后调用另一个方法,甚至只是console.log ...因为它还没有影响文件,我在显示该文件的地方得到了“ undefined”对象。
当然,如果我设置了一个超时,它可以工作,但这意味着它之后的所有内容都必须处于超时状态……我也可以在调用它的方法中很好地设置一个超时,但是随后这会也变得异步。
我尝试了很多事情,但我并没有真正得到承诺和类似的东西,所以...我完全被困在那里!
这是我的代码的(非常)简化版本,我知道它远非最佳(我是一个初学者),但无论如何这里都是这样:
var ParentClass = function ()
{
// Attributes and stuff
this.paths = [];
}
var MyClass = function ()
{
ParentClass.call( this );
}
MyClass.prototype.getInlineDOMdata = function ( selector )
{
// Stuff going on...
let querySelector = document.querySelectorAll( selector + " path" );
for ( let i = 0; i < querySelector.length; i++ )
{
this.paths.push(
{
name: querySelector[ i ].id,
color: querySelector[ i ].style.fill,
pathData: querySelector[ i ].attributes.d.value
}
);
}
}
MyClass.prototype.getInlineData = function ( inlineCode )
{
let domTarget = document.querySelector( "body" );
domTarget.innerHTML += `<div class="placeholder">${ inlineCode }<div>`;
let domContainer = document.querySelector( ".placeholder" );
// Stuff going on...
this.getInlineDOMdata( ".placeholder svg" );
domContainer.remove();
}
MyClass.prototype.getDataFromFile = function ( url )
{
fetch( url )
.then( response => response.text() )
.then( data => this.getInlineData( data ));
}
程序方面看起来像这样:
document.addEventListener( "DOMContentLoaded", loadComplete );
function loadComplete ()
{
var test = new MyClass();
test.getInlineData( `
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 195 82">
<!--Some SVG code -->
</svg>
` );
console.log( test.paths[ 0 ] ); // Object { name... }
console.log( test.paths.length ); // 4
test.getInlineDOMdata( "svg" );
console.log( test.paths[ 0 ] ); // Object { name... }
console.log( test.paths.length ); // 4 */
test.getDataFromFile( "https://upload.wikimedia.org/wikipedia/en/c/ce/SVG-logo.svg" );
console.log( test.paths[ 0 ] ); // undefined
console.log( test.paths.length ); // 0
setTimeout( function ()
{
console.log( test.paths[ 0 ] ); // Object { name... }
console.log( test.paths.length ); // 4
}, 1000 );
}
因此,当我使用getInlineData时,它可以工作。 当我使用getInlineDOMdata时,它可以工作。 当我使用getDataFromFile时,它不会!但是,如果我放了一个计时器,它就可以了。
我发现这确实是“肮脏的”,我迫切希望找到一个合适的解决方案,在这里我可以直接调用其他方法直接调用此方法!
编辑:已解决!
使用async
/ await
,只需将我的方法getDataFromFile
更改为
MyClass.prototype.getDataFromFile = async function ( url )
{
let response = await fetch( url )
.then( response => response.text() );
await this.getInlineData( response );
}
和程序方面,在async
函数之前添加loadComplete
,并在await
行之前添加test.getDataFromFile( "urlToSvg.svg" );
解决了我的问题!
感谢Leftium提供的伟大的教学语言(tutorial),这使我终于明白了诺言的实现方式
答案 0 :(得分:1)
使用async
/ await
。这些关键字基本上是诺言的语法糖,因此了解诺言的工作方式将非常有帮助。
这是一个很棒的tutorial,它使用Promise遍历了一个异步示例,然后将其转换为async / await语法。相关报价:
好消息是JavaScript允许您编写 伪同步代码,用于描述异步计算。异步 函数是隐式返回promise的函数,并且可以 在其主体中,以看起来同步的方式等待其他承诺。
...
在异步函数中,可以将await放在前面 表达等待解决的诺言,然后继续 功能的执行。
这样的函数不再像常规的JavaScript函数那样运行 从头到尾一口气。而是可以将其冻结在任何位置 等待的时间点,可以在以后的时间恢复。