uniapp 中使用getAPP 创建了全局变量,值是一个类实例,更改属性之后getAPP获取不到最新的值?
我写了一个限制请求数量的类文件,在getAPP中创建这个实例,然后加入方法,然后再获取请求的数量,数量一直是0,没有更新。
/** *@description *@author cy *@date 2022-10-20 09:52 **/export class LimitRequest { private limit: number = 1; // 限制并发数量 private currentSum: number = 0; // 当前发送数量 private requests: Array<any> = []; // 请求 constructor(limit: number) { this.limit = limit; this.currentSum = 0; this.requests = []; } public request(reqFn: Function) { if (!reqFn || !(reqFn instanceof Function)) { console.error('当前请求不是一个Function', reqFn); return; } this.requests.push(reqFn); if (this.currentSum < this.limit) { this.run(); } } public stop() { this.requests = []; this.currentSum = 0; } public getParam() { return { currentSum: this.currentSum, requests: this.requests.length }; } async run() { try { ++this.currentSum; const fn = this.requests.shift(); await fn(); console.error('this.requests', this.requests.length); } catch (err) { console.log('Error', err); } finally { --this.currentSum; if (this.requests.length > 0) { this.run(); } } }}
加入request方法模拟请求,
globalData: { limitAjax: new LimitRequest(10) }, for (let i = 0; i < 20; i++) { getApp().globalData.limitAjax.request(() => { setTimeout(() => { let params = getApp().globalData.limitAjax.getParam(); console.error('parma', params); }, 1000) }) }
打印中的request.length 一直是0,这是为什么呢?求助
因为调用 request
时传入的方法没有返回 Promise
for (let i = 0; i < 20; i++) { getApp().globalData.limitAjax.request(() => { return new Promise((resolve) => { setTimeout(() => { let params = getApp().globalData.limitAjax.getParam(); console.error("parma", params); resolve(); }, 1000); }); });}
这个问题发生的原因是JavaScript中的闭包和异步操作。在JavaScript中,函数是一级对象,这意味着函数可以作为其他函数的参数传递,并且可以作为其他函数的返回值。当你在LimitRequest
类的request
方法中返回一个函数时,这个函数会捕获到request
方法执行时的环境,并记住这个环境。这就是所谓的闭包。
在你的代码中,你创建了一个闭包,它引用了LimitRequest
类的requests
数组。然后你开始在for
循环中创建请求,每个请求都是一个闭包。当你在异步函数中(如setTimeout
)使用这些闭包时,它们仍然引用了创建它们的上下文,即LimitRequest
类的实例。
然而,当你更改LimitRequest
实例的状态(如调用stop
方法清空requests
数组)时,这个状态更改并不会影响到已经创建的闭包。因为闭包已经捕获了request
方法执行时的requests
数组的状态,而这个状态在闭包创建后就不会再改变。所以,当你尝试获取请求数量时,你看到的是0,因为闭包引用的requests
数组仍然是空的。
要解决这个问题,你需要确保在每次请求时都创建一个新的LimitRequest
实例,而不是共享同一个实例。这样,每个请求都有自己的状态,不会受到其他请求的影响。
例如,你可以将创建实例的代码移到request
方法中:
for (let i = 0; i < 20; i++) { getApp().globalData.limitAjax.request(() => { const limitAjax = new LimitRequest(10); setTimeout(() => { let params = limitAjax.getParam(); console.error('parma', params); }, 1000); });}
这样,每个闭包都会捕获到它自己的LimitRequest
实例的状态,而不是共享同一个实例的状态。这样,你就可以正确地获取到每个请求的参数了。
问题内容: 我刚刚创建了angularJS应用程序。 这是我的 index.html app.js 我有login.html,register.html和forgotpassword.html,home.html。每个人在单独的文件中都有单独的控制器。login.js,register.js,forgot.js,home.js。 login.js 同样,我在其他控制器中也有post方法。 我想要的
问题内容: 我了解的这段代码。我们复制A并将其称为C。当A更改时,C保持不变 但是当A是一个数组时,我们会有不同的情景。C不仅会改变,而且甚至在我们碰到A之前都会改变 有人可以解释第二个示例中发生的情况吗? 问题答案: Pointy的答案有很好的信息,但这不是此问题的正确答案。 OP所描述的行为是一个错误的一部分,该错误于2010年3月首次报告,并于2012年8月为Webkit进行了修补,但截至本
这段代码我懂。我们复制a并称之为C。当a被改变时,C保持不变 但是当A是一个数组时,我们有一个不同的判断。不仅C会改变,它甚至在我们接触A之前就改变了 有人能解释一下第二个例子中发生了什么吗?
当你使用了一个未知的变量名,通常 JavaScript 会自动创建全局变量: function f() { foo = 123 } f() foo 123 好在你会在 ECMAScript5 的严谨模式得到警告[1]: function f() { 'use strict'; foo = 123 } f() ReferenceError: foo is not defined 参考 [1] Jav
检索给定节点resp的所有属性名(而不是属性值!)的Xpath表达式看起来如何。xml标签? 假设以下XML文档: Xpath//title/@*会选择“eng,fr,easyreading”,但哪个Xpath会选择“lang,lang,type”?
问题 你想创建一个新的拥有一些额外功能的实例属性类型,比如类型检查。 解决方案 如果你想创建一个全新的实例属性,可以通过一个描述器类的形式来定义它的功能。下面是一个例子: # Descriptor attribute for an integer type-checked attribute class Integer: def __init__(self, name):