调用函数时异步等待不起作用
Posted
技术标签:
【中文标题】调用函数时异步等待不起作用【英文标题】:Async wait is not working when calling a function 【发布时间】:2021-06-14 13:33:54 【问题描述】:var value = await this.upload();
if (value == true)
this.item.photos = this.uploaded;
this.item.price = null;
this.item.qty = null;
this.dataSrv.addItem(this.item)
.then(() =>
this.dataSrv.stopLoading();
this.dataSrv.toast('Item Added Successfully');
this.item = as Item;
this.pictures = ['', '', '', ''];
this.uploaded = [];
this.photos = ['', '', '', ''];
)
.catch(err =>
this.dataSrv.stopLoading();
this.dataSrv.toast('Error While Adding Item. Try Again Later');
console.log(err);
);
在上面的代码中,我正在调用上传函数将图片上传到谷歌存储,我正在等待,所以我可以将图片链接添加到上传的数组中,这会将其保存到 this.item.photos 但它不会等待,而是直接执行真实条件。
async upload(image?)
var counter = 0;
this.pictures.forEach(i =>
if (i != '')
let temp: string = (i) as string;
temp = temp.replace("data:image/jpg;base64, ", '');
temp = temp.replace("data:image/jpg;base64,", '');
temp = temp.replace('must use [property]=binding:', '');
temp = temp.replace('SafeValue', '');
temp = temp.replace('(see https://g.co/ng/security#xss)', '');
const randomId = Math.random().toString(36) + Math.random().toString(36) + Math.random().toString(36) + Math.random().toString(36);
const uploadTask = this.storage.ref('items/').child(randomId).putString(temp, 'base64',
contentType: 'image/png'
);
uploadTask
.then(response =>
console.log("uploaded");
console.log(response);
this.storage.ref('items/' + randomId).getDownloadURL().subscribe(url =>
this.uploaded.push(url);
counter++;
);
)
.catch(err =>
console.log('not uploaded');
);
);
if (counter != this.uploaded.length)
return false;
else
return true;
我尝试在上传函数中返回 Promise 类型,但没有任何改变 我也尝试在函数调用之后执行 then 但同样的问题发生了
注意图片数组包含base64图片
【问题讨论】:
我认为你应该在upload
函数中返回一个承诺。否则你不会等待uploadTask
终止。
我已经尝试将它作为异步上传(图片?):Promise 但它仍然没有等待
它似乎返回了一个uploadTask,这不是一个承诺,你必须将它包装在一个承诺中。 :See here
【参考方案1】:
async
函数不会自己阻塞。问题是forEach
是同步调用的,但它包含的代码将异步运行。
这样做的常见模式:
async upload(image)
// use .map instead of .forEach
// from the callback function we return a Promise, so the result would be
// an array of promises
const promises = this.pictures.map(i =>
// your logic here
// you must return the promise
return uploadTask
.then(response => /* ... */ )
.catch(() => /* ... */ );
)
// Wait for all promises to be resolved.
// Note for the future: Promise.all will reject if at least 1 promise rejects.
// Your code seems to handle this case and converts a failed Promise into a success inside of `.catch` above.
await Promise.all(promises);
// here, the counter should be correct
【讨论】:
你确定Promise.all
可以处理promise 以外的对象吗? (一个 then-able 对象就足够了?)
@XouDo Promise.all 以神秘的方式工作 :) - 在您的浏览器控制台中尝试:Promise.all([1,2]).then(result => console.log(result))
。它将记录[1, 2]
。这些不是承诺,但Promise.all
将它们解析为成功。
你说得对,我试过了,最重要的是,它也适用于手工制作的 thenable 对象。
我仍然有同样的问题..我已经将我的代码编辑为上面的代码,我在 Promise.all(promises) 之后做了一个 then 并且它也不起作用以上是关于调用函数时异步等待不起作用的主要内容,如果未能解决你的问题,请参考以下文章