uni-app promise+await容易引起崩溃
uni-app promise+await容易引起崩溃
产品分类:
uniCloud/App
示例代码:
for (let i = 0; i < 1500; i++) {
await new Promise((resolve) => setTimeout(resolve, 100))
console.log(`${i}`)
}
console.log(`all-done`)
操作步骤:
如上
预期结果:
如上
实际结果:
如上
bug描述:
Promise+await比较多的情况下,容易崩溃,以下代码在服务器端必然崩溃。而且没有报错信息,就是一个失败,前面执行的代码打印的日志也能看见。
更多关于uni-app promise+await容易引起崩溃的实战教程也可以访问 https://www.itying.com/category-93-b0.html
说下结论吧,在阿里云上面:
定时器触发的函数,可以执行到600秒;
client-call的方式触发,可以执行到10秒多点;
测试方法:
设置超时时间为600
代码里面循环千次,每次sleep 1秒
日志方式做了俩个,一个是控制台log,另外一个是写了一个表做日志
测试结果:
定时器可以实实在在的执行600秒,控制台日志有点乱序,但是数据表的日志是完善的;
client call可以执行到10秒到12秒,客户端超时,而且服务器端也abort了。
其它:
官方更新后的文档说明【非定时触发最高只支持60s超时时间】,这个也是误导性的。client call的服务器端执行时间就是10秒,不是60秒。如果说客户端超时10秒,但是服务器端还可以继续执行50秒,那就可以将结果写入到临时表,然后client去loop结果,这样就可以突破10秒限制了。
腾讯云的云函数测试效果好些,但是即使是付费版,多数资源还不如阿里云的免费版。
我个人是做服务器端的,之前管的app日活千万多,现在的也是几百万。重量级的项目做多了烦了,第一次看见uniapp和unicloud,真的是欣喜若狂。所以希望这个平台越来越完善,看见他走到天尽头。不过在正式使用中,发现很多细节需要打磨,产品文档和功能。写个普通的小玩意,增删改查的的确很容易,超级容易!超级帅!但是系统级的工作稍微繁复一点,就有很多不便利。
更多关于uni-app promise+await容易引起崩溃的实战教程也可以访问 https://www.itying.com/category-93-b0.html
使用中有任何问题都可以提出来,我们会积极采纳用户的意见
回复 DCloud_uniCloud_WYQ: 看见你们会积极采纳,所以我也积极认真的提 :)
为什么要创建这么多的promise
要做复杂点的工作,综合计算,读写外部数据,产生的promise比这个多很多。案例只不过是找到了崩溃的原因后,做的最简sample展示。
是不是云函数超时了,或者内存超出了
超时这样的低级错误不至于。内存更不会超过,这个代码是很小的。
回复 e***@sina.com: 如果是阿里云的话你看到的失败可能只是日志服务的失败。另外你这个云函数执行了150秒是怎么测试的?定时触发还是客户端请求的
回复 DCloud_uniCloud_WYQ: 没有执行那么久,我测试时候,做了很多的不同场景,所以就写个大点的数。 实际上一般执行很难超过13秒,设置的超时是55秒,或者550秒,结果都一样。 范例代码很简单,可以拷贝做个试验,结果一目了然,就不用这样反复的来回沟通了。 我也用了nodejs12来处理,还是跟8一样的。 最大的差别是:本地化运行云函数,就正常的。
回复 e***@sina.com: 沟通还是必要的,因为这个表现在非定时触发调用的情况下是正常的
回复 e***@sina.com: 只有定时触发可以使用10秒以上的超时时间
回复 e***@sina.com: web控制台上非定时触发60秒的描述有误,我们调整下
回复 DCloud_uniCloud_WYQ: 是啊!!我刚才发现了你们修改了控制台的说明,也在别的文档里面找到了!!! 真的是太疯狂了。。。。 文档写的是那样,执行的是另外一样,我发帖时候就怀疑了是10秒的平台限制,但是看见官方的答复一直没有这个。
回复 e***@sina.com: 这个信息之前阿里同步的时候有误,导致文档也写错了,后来找阿里确认了之后忘记改文档了
在uni-app中使用Promise+await处理大量异步操作时,确实可能遇到性能问题甚至崩溃。根据你提供的代码,问题主要在于:
-
同步循环中的连续await:你的代码在循环中连续创建了1500个Promise并依次等待,每个间隔100ms。虽然每个Promise本身是异步的,但循环本身是同步的,会快速创建大量微任务。
-
内存和堆栈压力:在Node.js环境(uniCloud云函数)或某些App环境下,快速创建大量Promise对象可能导致:
- 内存使用量激增
- 事件循环队列过载
- 垃圾回收压力增大
-
超时问题:1500个100ms的等待总共需要150秒(2.5分钟),云函数可能有执行时间限制。
解决方案:
- 批量处理:将任务分组处理
async function processBatch(batchSize) {
for (let i = 0; i < 1500; i += batchSize) {
const promises = [];
for (let j = 0; j < batchSize && i + j < 1500; j++) {
promises.push(new Promise(resolve =>
setTimeout(() => {
console.log(`${i + j}`);
resolve();
}, 100)
));
}
await Promise.all(promises);
}
console.log('all-done');
}
- 控制并发:使用专门的并发控制库或简单实现
class TaskQueue {
constructor(concurrency) {
this.concurrency = concurrency;
this.running = 0;
this.queue = [];
}
add(task) {
return new Promise((resolve, reject) => {
this.queue.push(() => task().then(resolve, reject));
this.next();
});
}
next() {
while (this.running < this.concurrency && this.queue.length) {
const task = this.queue.shift();
this.running++;
task().finally(() => {
this.running--;
this.next();
});
}
}
}

