简体   繁体   中英

Async Javascript not accessing class method

I'm seeing something weird with some async Javascript accessing a class method.

I have some Javascript that does a fairly intensive search, which can take some time (about 1 minute), so I want to run it asynchronously.

Here's my MVCE:

<html>
    <head>
        <script
              src="https://code.jquery.com/jquery-3.5.1.min.js"
              integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0="
              crossorigin="anonymous"></script>
    </head>
    <body>
        <div id="search-form">
            <input id="search-terms" type="text" placeholder="enter search terms" />
            <button id="search-button">Search</button>
        </div>
    </body>
    <script type="text/javascript">

        class Index {

            constructor() {
                this.internal_hash = {};
            }

            get_term_count(){
                return Object.keys(this.internal_hash).length;
            }

            do_big_long_expensive_calculation(){
                var i=0;
                for(i=0; i<10000; i++){
                    this.internal_hash[i] = i+1;
                }
                return i;
            }

            search_text(text){
                var results = this.do_big_long_expensive_calculation();
                return results;
            }

        };

        var search_index = new Index;
        var search_results = null;

        $(document).ready(function(){

            async function searchIndex(){
                let text = $('#search-terms').val();
                console.log('searching index for text:'+text);
                console.log('using index with terms:'+search_index.get_term_count());
                search_results = search_index.search_text(text);
                console.log('results:'+search_results.length);
                return search_results;
            }

            $('#search-button').click(function(){
                console.log('search button clicked')
                var el = $(this);
                el.prop("disabled", true);
                el.text('Searching...');
                searchIndex()
                    .then(function(){
                        console.log('search results found:'+(search_results.length));
                        el.text('Search');
                        el.prop("disabled", false);
                    })
                    .catch(reason => console.log(reason.message));
            });

        });
    </script>
</html>

If I call:

 search_index.search_text('sdfssdfsf')

from the browser's console, it returns the expected 10000 .

However, if I click the search button, the console.log statement prints out undefined for the value returned by search_index.search_text .

Why is this? The only thing I can think of is there's some characteristic of async I'm not aware of. Does async Javascript not have access to the same memory as the normal synchronous execution model?

You cant get length of number, return number directly or convert to string and get length

 <html> <head> <script src="https://code.jquery.com/jquery-3.5.1.min.js" integrity="sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=" crossorigin="anonymous"></script> </head> <body> <div id="search-form"> <input id="search-terms" type="text" placeholder="enter search terms" /> <button id="search-button">Search</button> </div> </body> <script type="text/javascript"> class Index { constructor() { this.internal_hash = {}; } get_term_count(){ return Object.keys(this.internal_hash).length; } do_big_long_expensive_calculation(){ var i=0; for(i=0; i<10000; i++){ this.internal_hash[i] = i+1; } return i; } search_text(text){ var results = this.do_big_long_expensive_calculation(); return results; } }; var search_index = new Index; var search_results = null; $(document).ready(function(){ async function searchIndex(){ let text = $('#search-terms').val(); console.log('searching index for text:'+text); console.log('using index with terms:'+search_index.get_term_count()); search_results = search_index.search_text(text); console.log('results:'+search_results); return search_results; } $('#search-button').click(function(){ console.log('search button clicked') var el = $(this); el.prop("disabled", true); el.text('Searching...'); searchIndex().then(function(){ console.log('search results found:'+(search_results)); el.text('Search'); el.prop("disabled", false); }).catch(reason => console.log(reason.message)); }); }); </script> </html>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM