首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >WeakMaps和AJAX调用

WeakMaps和AJAX调用
EN

Stack Overflow用户
提问于 2017-01-25 19:45:30
回答 2查看 66关注 0票数 0

当我用巴别塔实践我到目前为止所学到的关于ES2015的知识,特别是关于WeakMaps的时候,我遇到了一个问题,我不知道为什么它不能工作。

我定义了一个WeakMap来存放来自AJAX调用的数据,只有在所述WeakMap的值为undefined时才会触发。

这就是我的想法:

代码语言:javascript
复制
class User {

    constructor( id ) {

        id = Number( id );

        if( id <= 0 || isNaN( id ) ) {
            throw new TypeError( 'Invalid User ID' );
        }

        _id.set( this, id );
    }

    getID() {
        return _id.get( this );
    }

    getData() {

        let _this = this;

        if( _data.get( _this ) === undefined ) {

            _this.loadData().done( function( data ) {

                // JSON is indeed successfully loaded

                console.log( data );

                _data.set( _this, data );

                // WeakMap is indeed set correctly

                console.log( _data.get( _this ) );
            });
        }

        // But here it's undefined again!

        console.log( _data.get( _this ) );

        return _data.get( _this );
    }

    loadData() {

        return $.get({
            url: '/users/' + _id.get( this, data ),
        });
    }
}

let _id   = new WeakMap;
let _data = new WeakMap;

// ---------------

var user = new User( 1 );

console.log( user.getID(), user.getData() ); // 1 undefined

据我所知,我设置的WeakMap数据是正确的,因为用户ID正在设置并且可以检索,但是来自AJAX的用户数据虽然确实是在jQuery.done()中设置的,但不能在它之外进行访问。

我哪里做错了?

EN

回答 2

Stack Overflow用户

发布于 2017-01-26 20:02:18

我不明白JavaScript说这是不是正确的解决方案,但我搜索了很多,在Stack Overflow中读到了无数的问题,其中有大量的答案,但对于任何感兴趣的人来说,都不能用简单的方式来解决问题:

代码语言:javascript
复制
class User {

    constructor( id ) {

        id = Number( id );

        if( id <= 0 || isNaN( id ) ) {
            throw new TypeError( 'Invalid User ID' );
        }

        _id.set( this, id );
    }

    getID() {
        return _id.get( this );
    }

    getData() {

        if( _data.get( this ) === undefined ) {
            _data.set( this, this.loadData() );
        }

        return _data.get( this );
    }

    loadData() {
        return $.getJSON( CARD_LIST + '/player/' + _id.get( this ) );
    }
}

let _data = new WeakMap;

// ---------------

var user = new User( 1 );

user.getData().done( function( data ) {

    console.log( data );
})

这不是我最初想要的,我也没有知识来解释“为什么”,但是,至少这是一个明显的工作例子,我谦虚地希望它能帮助其他试图从非常长的答案和/或无用/无指导的评论中提取信息的人。

票数 0
EN

Stack Overflow用户

发布于 2017-01-26 20:39:56

有关如何使用Ajax等异步操作的结果的(冗长)入门,请参阅How do I return the response from an asynchronous call?

简短的答案是:如果您正在同步一个值,那么就不能使用return异步获取的结果。您的getData函数在任何Ajax调用解析之前返回,因此getData的同步返回值不能依赖于任何异步获取的值。必须在处理任何新事件之前完全解决。处理异步Ajax结果是一个新事件,因此在getData函数执行成为历史之前,您的done处理程序不一定会运行。

解决问题的两种一般方法是:

使Ajax调用synchronous

  • Make能够在getData

外部异步访问

  1. 获取的值

可以通过将回调传递到getData来执行#2,如下所示

代码语言:javascript
复制
getData(funnction(data) { console.log("If this is running, we finally got the data", data); }

function getData(callback) {
    _this.loadData.done(function(data) {
        _data.set(this, data);
        // etc. etc.
        callback(_data.get( _this ));
    });
}

那么,现在getData本身是异步的,这是否迫使你重写你已经拥有的任何` `getData的用法,并导致异步模式在你的代码中传播?是的,确实如此。

如果你想使用return a promises,你可以这样做

代码语言:javascript
复制
getData().then(function(data) {
    console.log("Got the data", data);
});

function getData() {
    return _this.loadData().then(function(data) {
        _data.set(this, data);
        // etc. etc.
        return _data.get( _this );
    });
}

这之所以有效,是因为promises允许链接then调用。这只是在get data函数内部和外部链接then:一个then回调在getData内排队,下一个在getData外排队。第一个回调的返回值用作第二个回调的参数。then的返回值是最初的promise,所以我简单地使用了表单return mypromise.then(...),它返回的对象就像我刚刚返回的return mypromise一样(但很明显,在这种情况下我没有设置回调)。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41850805

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档