虽然使用异步方法的数组循环只需要角度为2的最后一个元素(ecma6)

时间:2015-12-02 20:16:02

标签: javascript ecmascript-6 angular

我有以下代码:

for( let filename of ["action", "course", "program", "staff", "student"]){
    http.get('data/'+filename+'.json').map(res => res.json()).subscribe(
               staff => localStorage.setItem(filename, JSON.stringify(staff)
            ));
}

转化为:

for (var _i = 0, _a = ["action", "course", "program", "staff", "student"]; _i < _a.length; _i++) {
    var filename = _a[_i];
    http.get('data/' + filename + '.json')
        .map(function (res) { return res.json(); })
            .subscribe(function (staff) { return localStorage.setItem(filename, JSON.stringify(staff)); });
            }

哪个应该循环一个stings数组,其中包含我希望在本地存储中加载json对象的文件名。

问题如下:
 我只获取存储在本地存储中的最后一个元素的值。其余的都没了。

原因是:
当需要拨打localStorage.setItem中的.subscribe()时 存储在filename中的值等于数组中的最后一个值。

我的想法

  1. 使HTTP请求同步 {确定这是一个坏主意}但应用程序实际上依赖于这些数据,因此我不介意阻止ui直到完成。 |无论如何ng2文件都没有显示如何做到这一点......
  2. 使用Promise,我不知道如何使用angular 2
  3. 找到一种方法来确保文件名值是每个循环存储的方式
  4. 忘记在循环中执行此操作并将其写入硬编码
  5. 我的代码

    app.ts

    import {Component,  bootstrap, NgFor,CORE_DIRECTIVES,OnInit,provide} from 'angular2/angular2';
    import {RouteConfig,  ROUTER_DIRECTIVES, ROUTER_PROVIDERS, RouteParams, RouteData,
        LocationStrategy, HashLocationStrategy,Location} from 'angular2/router';
    import {Http, HTTP_PROVIDERS} from 'angular2/http';
    
    @Component({    
        selector: 'app-holder',
        template: `<router-outlet></router-outlet>`,
        viewProviders: [HTTP_PROVIDERS],
        directives: [ROUTER_DIRECTIVES]]
    })
    export class MainComponent {
        constructor(http: Http) {
            if(dataStorage.shouldLoad()){
                for( filename of ["action", "actiontype", "advisertype", "course", "program", "staff", "student"]){
                    http.get('data/'+filename+'.json').map(res => res.json()).subscribe(staff => localStorage.setItem(filename, JSON.stringify(staff)));
                }
            }
        }
    }
    
    bootstrap(MainComponent,[ROUTER_PROVIDERS, provide(LocationStrategy, {useClass: HashLocationStrategy})]);
    

    index.html

    <html>
    <head>
        <title>Star App</title>
        <!-- Bootstrap -->
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
        <script src="../node_modules/systemjs/dist/system.src.js"></script>
        <script src="../node_modules/angular2/bundles/angular2.dev.js"></script>
        <script src="../node_modules/angular2/bundles/router.dev.js"></script>
        <script src="../node_modules/angular2/bundles/http.dev.js"></script>
        <script>
            System.config({
                packages: {'app': {defaultExtension: 'js'}}
            });
            System.import('app/app');
        </script>
    </head>
    <body>    
        <app-holder>Please wait while Loading...</app-holder>
    </body>
    </html>
    

    backGround checkes:

3 个答案:

答案 0 :(得分:1)

你刚刚落到infamous closure in a loop issue

你认为ES6可以通过它的块范围来拯救你吗?是的,确实如此,但前提是您确实声明您的变量:

for (let filename of ["action", "course", "program", "staff", "student"]) {
//   ^^^ 
    http.get('data/'+filename+'.json')
      .map(res => res.json())
      .subscribe(staff => localStorage.setItem(filename, JSON.stringify(staff)));
}

答案 1 :(得分:0)

我不认为这是一个角度问题。

这可能有所帮助:

Promise.all(
  filenames.map(
    f => http.get('data/'+filename+'.json')))
.then(results => results
  .forEach((r, i) => localStorage.setItem(fileNames[i], r)));

答案 2 :(得分:0)

基于@dandavis注释我找到解决问题的最简单方法是在列表数组上使用forEach!

修改后的代码:

["action", "course", "program", "staff", "student"].forEach(filename => 
    http.get('data/'+filename+'.json').map(res => res.json()).subscribe(
         staff => localStorage.setItem(filename, JSON.stringify(staff)));
     )