我有一个类似以下内容的课程:
class Loader
{
async load()
{
let pending = [...];
return new Promise( (resolve, reject) =>
{
while(pending.length > 0)
{
await this._loadAsset(pending.pop());
}
resolve();
});
}
async _loadAsset(asset)
{
return new Promise( (resolve, reject) =>
{
// Loading logic goes here, eventually calling...
resolve();
});
}
}
({pending
是一个对象数组,我懒得在这里列出。)
我遇到的问题是,当我尝试加载脚本时,Chrome给我一个Uncaught SyntaxError: await is only valid in async function
错误。据我所知,Loader的load
和_loadAsset
方法都已声明为异步。我想念什么? while循环会使事情复杂吗?
答案 0 :(得分:2)
回调函数未声明为async
,因此您可以尝试添加如下异步代码:
return new Promise( async (resolve, reject) =>
{
while(pending.length > 0) {
await this._loadAsset(pending.pop());
}
resolve();
});
是解决许多未决承诺的更好选择
答案 1 :(得分:2)
您可以将load
函数简化为:
async load()
{
let pending = [...];
while(pending.length > 0)
{
await this._loadAsset(pending.pop());
}
}
不需要内部承诺构建。
您也可以这样做:
load()
{
let pending = [...];
return Promise.all(pending.map(i => this._loadAsset(i)));
}
答案 2 :(得分:0)
问题是您传递给Promise
构造函数的匿名函数使用await
,但未声明为async
:
return new Promise( (resolve, reject) => // this function uses await but is not async
{
while(pending.length > 0)
{
await this._loadAsset(pending.pop());
}
resolve();
});
通常,如果您不包装需要回调的内容,则无需使用Promise
构造函数。在这种情况下,您根本不需要它,只需将while循环作为load
主体的一部分即可:
async load()
{
let pending = [/*...*/];
while(pending.length > 0)
{
await this._loadAsset(pending.pop());
}
}
答案 3 :(得分:0)
您不应从async
函数返回承诺。这是因为在幕后,从async
函数返回的任何值都将包装在一个promise中:
// The following function
async function foo() {
await someAsyncFunction();
return "done";
}
// Is the same as
function bar() {
return new Promise((resolve) => {
someAsyncFunction().then(() => resolve("done"));
});
}
因此,您的代码应重写为:
class Loader
{
async load()
{
let pending = [...];
while(pending.length > 0)
{
await this._loadAsset(pending.pop());
}
}
async _loadAsset(asset)
{
// Loading logic happens here, but instead of calling resolve(), just return. Remember to add await to any async operation.
}
}