为了账号安全,请及时绑定邮箱和手机立即绑定

为什么我的变量在函数内部修改后没有变化? - 异步代码引用

为什么我的变量在函数内部修改后没有变化? - 异步代码引用

鉴于以下示例,为什么outerScopeVar在所有情况下都未定义?var outerScopeVar;var img = document.createElement('img');img.onload = function() {     outerScopeVar = this.width;};img.src = 'lolcat.png';alert(outerScopeVar);var outerScopeVar;setTimeout(function() {     outerScopeVar = 'Hello Asynchronous World!';}, 0);alert(outerScopeVar);// Example using some jQueryvar outerScopeVar;$.post('loldog', function(response) {     outerScopeVar = response;});alert(outerScopeVar);// Node.js examplevar outerScopeVar;fs.readFile('./catdog.html', function(err, data) {     outerScopeVar = data;});console.log(outerScopeVar);// with promisesvar outerScopeVar;myPromise.then(function (response) {     outerScopeVar = response;});console.log(outerScopeVar);// geolocation APIvar outerScopeVar;navigator.geolocation.getCurrentPosition(function (pos) {     outerScopeVar = pos;});console.log(outerScopeVar);为什么undefined在所有这些例子中输出?我不想要解决方法,我想知道为什么会这样。
查看完整描述

3 回答

?
吃鸡游戏

TA贡献1829条经验 获得超7个赞

对于正在寻找快速参考的人以及使用promises和async / await的一些示例,这里有一个更简洁的答案。

对于调用异步方法(在本例中setTimeout)并返回消息的函数,从朴素方法(不起作用)开始:

function getMessage() {
  var outerScopeVar;
  setTimeout(function() {
    outerScopeVar = 'Hello asynchronous world!';
  }, 0);
  return outerScopeVar;}console.log(getMessage());

undefined在这种情况下记录,因为getMessagesetTimeout调用回调之前返回并更新outerScopeVar

解决它的两种主要方法是使用回调承诺

回调

这里的更改是getMessage接受一个callback参数,该参数将被调用以在可用时将结果传递回调用代码。

function getMessage(callback) {
  setTimeout(function() {
    callback('Hello asynchronous world!');
  }, 0);}getMessage(function(message) {
  console.log(message);});

承诺

Promise提供了一种比回调更灵活的替代方案,因为它们可以自然地组合起来协调多个异步操作。甲承诺/ A +标准实现天然地在node.js中(0.12+)和许多当前浏览器提供的,而是在像库还实现蓝鸟Q

function getMessage() {
  return new Promise(function(resolve, reject) {
    setTimeout(function() {
      resolve('Hello asynchronous world!');
    }, 0);
  });}getMessage().then(function(message) {
  console.log(message);  });

jQuery Deferreds

jQuery提供的功能类似于Deferreds的promises。

function getMessage() {
  var deferred = $.Deferred();
  setTimeout(function() {
    deferred.resolve('Hello asynchronous world!');
  }, 0);
  return deferred.promise();}getMessage().done(function(message) {
  console.log(message);  });

异步/ AWAIT

如果您的JavaScript环境包括支持asyncawait(如Node.js的7.6+),那么你就可以在同步使用承诺async的功能:

function getMessage () {
    return new Promise(function(resolve, reject) {
        setTimeout(function() {
            resolve('Hello asynchronous world!');
        }, 0);
    });}async function main() {
    let message = await getMessage();
    console.log(message);}main();


查看完整回答
反对 回复 2019-05-20
  • 3 回答
  • 0 关注
  • 1228 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信