在异步函数或 Promise 中设置全局变量的值? [复制]
Posted
技术标签:
【中文标题】在异步函数或 Promise 中设置全局变量的值? [复制]【英文标题】:Set value of global variable inside async function or inside promise? [duplicate] 【发布时间】:2020-04-16 01:14:43 【问题描述】:首先我想问一下这是否可能,在异步函数或promise中为全局变量设置值?
如果是,那么为什么每个可用的教程/网站都在教程中使用 console.log(results) 但从不使用它将其分配给变量。
例如:
var promise1 = new Promise(function(resolve, reject)
resolve('foo');
);
let myval="";
promise1.then(function(value)
myval=value;
console.log(value); // this logs "foo"
);
console.log(myval); //this logs blank
【问题讨论】:
你知道//this logs blank
在//this logs "foo"
之前被调用是因为promise造成的延迟吗?
是的,我非常清楚这一点。我的问题是如何为变量 myval 赋值(假设 myval 是全局的)。
代码不是问题,但解释才是问题。如果您需要将全局变量设置为 Promise 中的某些内容,有两种方法可以处理此问题 - 等待一些随机时间,这显然不是 100% 正确,因为它可能会或可能不会起作用。取决于 promise 需要多长时间来解决 - 如果您真的需要全局变量,请确保在 promise 链中使用它们。因此,在您的示例中,不要在承诺链之外进行控制台日志,而是将其作为下一个然后使用。
【参考方案1】:
这会将全局变量 myval
更改为 'foo'
但在调用 console.log(myval);
时,由于超时,承诺尚未解决,即使您立即解决承诺,它仍然只会更改它在console.log(myval);
运行之后,因为承诺将作为microtask 排队。
我会添加一个 setTimeout 来等待分配,或者添加一个 setInterval 来检查它何时发生。
var promise1 = new Promise(function(resolve, reject)
resolve('foo'););
let myval="";
promise1.then(function(value)
myval=value;
console.log(value); // this logs "foo"
);
setTimeout(() => console.log(myval), 1000); //this logs 'foo'
【讨论】:
我的问题是如何将值分配给 myval 。我知道承诺。 这就是我的回答确认它仍然会更改/将值分配给myval
。如果你想使用它,那么你必须等待分配发生。例如在setInterval
中检查它
我已经更新了我的问题,我已经删除了 setTimeout 。它仍然不会为 myval 设置值。
如果你知道promise,你就会知道console.log(myval);
会是空白的,因为它在你的then
回调function(value) myval=value; console.log(value); // this logs "foo"
之前运行。尝试将 console.log(myval);
放入 100 毫秒的 setTimeout
中,看看有什么不同
你不是在myval=value;
那里做吗?【参考方案2】:
如果你想访问 myval
的更改版本(也就是说,在 Promise 中的赋值完成后执行你的代码),你需要跟进另一个 then
,或者做任何其他事情这会将您的代码在分配后放入事件队列中。
var promise1 = new Promise(function(resolve, reject)
resolve('foo');
);
let myval="a";
promise1.then(function(value)
myval=value;
console.log(value); // this logs "foo"
);
setTimeout(() => console.log(myval), 0); // logs "foo"
var promise1 = new Promise(function(resolve, reject)
resolve('foo');
);
let myval="a";
promise1.then(function(value)
myval=value;
console.log(value); // this logs "foo"
).then(function()
console.log(myval) // logs "foo"
);
还有一个 await 示例,可能是您正在寻找的示例:
将所有内容包装到一个立即调用的异步函数中,这样我们就可以在里面使用await
将.then
承诺保存到一个变量中(显然,您可以完全省略该变量并直接await
)
await
在你的 console.log
之前的那个承诺
(async () =>
var promise1 = new Promise(function(resolve, reject)
resolve('foo');
);
let myval="";
var thenedPromise = promise1.then(function(value)
myval=value;
console.log(value); // this logs "foo"
);
await thenedPromise; // wait before the promise generated by "then" is resolved
console.log(myval); // logs "foo"
)();
【讨论】:
我以后如何在我的脚本中使用myval
你不使用异步?还是那不可能?
@BrianWiley 最好使用异步/等待。您不能在“脚本的后面”使用它,只能在 .then
回调中使用。【参考方案3】:
这完全是关于 javascript 的异步行为。请参阅下面的 sn-p 并注意执行顺序。 value
在解决承诺后已经分配给 myval
。在您的情况下,您只需要维护一个标志,无论该特定承诺是否已解决,然后如果您尝试获取 myval
变量的值,您将获得所需的输出。是的,这是实现这一目标的众多方法之一。
let myval="";
var promise1 = new Promise(function(resolve, reject)
resolve('foo');
);
promise1.then(function(value)
myval=value;
console.log("Value :" + value);
console.log("myval after promise : " + myval);
);
console.log("myval before promise : " + myval);
【讨论】:
以上是关于在异步函数或 Promise 中设置全局变量的值? [复制]的主要内容,如果未能解决你的问题,请参考以下文章
如何在 promise 中设置 react hook 的值?