【问题标题】:A little bit confused about javascript promise对 javascript Promise 有点困惑
【发布时间】:2019-12-12 02:00:59
【问题描述】:

我正在尝试使用 Promise 使我的代码正常工作。

阅读和播放,创建了以下代码的平静,试图在“githubUserData”对象中设置一些属性。 Promise 似乎有效,但“githubUserData”返回 {}(空)

显然,正如我的控制台日志显示的那样,我的代码没有按所需的顺序执行。它在他的属性设置之前显示对象..

    console.clear();
    console.log( '>>>>>> Starting promise..' );

    // Create object to keep requested data
    let githubUserData = {};

    function getGithubUserData() {
        // Promise
        return new Promise( ( resolve, reject ) => {
            $.ajax({
                url: 'https://api.github.com/users/codepen',
                data: {},
                success: function( data ) {
                    resolve( data ); // Resolve promise and go to then()
                },
                error: function( err ) {
                    reject( err ); // Reject the promise and go to catch()
                }
            });
        });
    };

    getGithubUserData().then( data => {
      // Promise request was successful
      console.log( '>>>>>> Data: ', data);
      console.log( '>>>>>> Data loaded: ' + data.id + ', ' + data.name + ', ' + data.type + ', ' + data.blog );
      githubUserData = {...data};
    }).catch( err => {
      // Promise rejected via reject()
      console.log( err );
    })

    console.log('>>>>>> Promise end. Data saved: ', githubUserData);

codepen 为此..
https://codepen.io/snart1/pen/KOXbNr?editors=0012

我在这里做错了什么?

如何不按以下顺序执行我的代码

1.>>>>>>开始承诺.. 2. >>>>>> 承诺结束。保存的数据:对象 {} 3. >>>>>> 数据加载:1545643,CodePen,Organization,http://codepen.io

但是这个(对象中有数据)

1.>>>>>>开始承诺.. 2. >>>>>> 数据加载:1545643,CodePen,Organization,http://codepen.io 3. >>>>>> 承诺结束。数据保存:对象 { data here }

PS。我更喜欢 JavaScript 解决方案,而不是 jQuery。

更新 我也尝试了 async/await,但得到了相同的结果(这段代码更接近我的目标)。

console.clear();
console.log( '>>>>>> Starting promise..' );

// Create object to keep requested data
let githubUserData = {};

async function getGithubUserData() {
    var xhr = new XMLHttpRequest();
    // Promise
    return new Promise( ( resolve, reject ) => {
       xhr.onreadystatechange = function() {
            if ( xhr.readyState == 4 ) {
                if ( xhr.status >= 300 ) {
                    reject( "Error, status code = " + xhr.status );
                } else {
                    resolve( JSON.parse( xhr.responseText ) );
                }
            }
        }
        xhr.open( 'get', 'https://api.github.com/users/codepen', true );
        xhr.send();
    });
}
async function logUserData() {
    try {
        let data = await getGithubUserData();
        console.log( '>>>>>> Data loaded: ' + data.id + ', ' + data.name + ', ' + data.type + ', ' + data.blog );
        githubUserData = {...data};
    } catch ( err ) {
       console.log( err );
    }
}
logUserData();

// My goal is to have githubUserData loaded with data here !!!!
console.log( '>>>>>> Promise end. Data saved: ', githubUserData );

用于异步/等待的 codepen pen
https://codepen.io/snart1/pen/ymzQvK?editors=0012

这里有什么办法可以有数据,console.log('>>>>>> Promise end. Data saved: ', githubUserData);
不在 getGithubUserData 调用内部,而是在之后?有没有办法让脚本执行直到那里有数据?
这是我的目标,在那里获取数据..

【问题讨论】:

  • 您的最终 console.log 正在同步运行,因此它会在您的异步函数解析之前执行。仅供参考,$.ajax 返回一个延迟的 Promise,因此您将一个 Promise 包装在一个已经异步的方法周围。
  • 注意:$.ajax 返回一个“thenable”(我不会称它为 Promise,但它已经足够接近了)因此,您可以删除 successerror 属性,只需返回$.ajax(....)
  • 我的代码中的人我正在使用 xtmhttpRequest.. 我在这里使用 ajax 来缩短代码..
  • 它不能解决问题,但您应该通过将console.log( '>>>>>> Starting promise..' ) 移到console.log('>>>>>> Promise end. Data saved: ', githubUserData) 上方来获得一些见解。你会发现一切都没有改变。没有任何改变的原因是githubUserData = {...data},在.then() 回调中,在那些console.log() 语句执行后的某个时间后,在稍后 javascript 线程中运行。也就是简而言之.then()的本质。

标签: javascript object ecmascript-6 promise es6-promise


【解决方案1】:

因为您在执行 then 之前正在记录。像这样使用finally

getGithubUserData().then(...).catch(...).finally(() => {
  console.log(githubUserData);
});

将数据分配给变量的异步代码在您实际记录变量后运行。

使用finally,因此无论是否导致错误,您都可以看到输出。

【讨论】:

  • 这里有什么办法可以有数据,console.log('>>>>>> Promise end. Data saved: ', githubUserData);不在 getGithubUserData 调用内部,而是在之后?有什么方法可以让脚本的执行直到那里有数据?
  • 如果你把它全部包含在一个async函数中,那么是的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-19
  • 2011-07-10
  • 2013-11-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多