在异步函数或 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 承诺保存到一个变量中(显然,您可以完全省略该变量并直接awaitawait 在你的 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 中设置全局变量的值? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

对于在同一类中设置全局变量的例程,啥是好的命名约定

37如何在函数中设置一个全局变量 ?

如何在 Laravel 中设置全局变量?

如何在 promise 中设置 react hook 的值?

如何在 promise 中设置 react hook 的值?

如何在另一个模块中设置全局变量?