为什么我不能使用rx.js使用.map映射我的数组

时间:2017-11-24 07:26:18

标签: javascript rxjs

我创建了一个简单的Observable管道。它调用一个端点,它返回一个人的数组,然后我想映射它。这是我的代码:

  Observable
    .fromPromise(fetch('/names').then(res => res.json()))
    .map(d => d.name)
    .subscribe(
        names => console.log("NAME", names),
        err => console.log(err),
        () => console.log('done')
    )

fetch行返回此数组

         [
            {
                name: 'Jason',
                age: 42
            },
            {
                name: 'Neely',
                age: 41
            },
            {
                name: 'Tristan',
                age: 21
            }
        ]

当我到达.map(d => d.name)时,我总是得到undefined。它没有迭代数组。代码试图在数组本身上调用.name。我试图在第一个之后放置另一个.map,但这并没有解决任何问题。我错过了什么?如何修复代码?

2 个答案:

答案 0 :(得分:3)

首先,如果fetch确实正在返回您所说的内容,那么它不是JSON,因此解析它(res.json())会失败。在JSON中,键必须是双引号,并且字符串必须是双引号。但假设它实际上是有效的JSON ......

Observable仅输出单个值,整个数组,而不是数组中条目的单个值。由于数组没有name属性,因此获得undefined

相反,要么:

  1. map来自res.json

  2. 的结果
  3. map来自Observable的单一属性

  4. 这是#1:

    Rx.Observable
        .fromPromise(
            fakeFetch('/names')
            .then(res => res.json())
            .then(a => a.map(d => d.name)) // <=====
        )
        .subscribe(
            names => console.log("NAME", names),
            err => console.log(err),
            () => console.log('done')
        );
    

    直播示例:

    function fakeFetch() {
        return new Promise(resolve => {
            setTimeout(resolve, 100,
            		{
                	json: function() {
                     return JSON.parse('[' +
                        '{' +
                            '"name": "Jason",' +
                            '"age": 42' +
                        '},' +
                        '{' +
                            '"name": "Neely",' +
                            '"age": 41' +
                        '},' +
                        '{' +
                            '"name": "Tristan",' +
                            '"age": 21' +
                        '}' +
                    ']');
                  }
                }
            );
        });
    }
    Rx.Observable
        .fromPromise(
            fakeFetch('/names')
            .then(res => res.json())
            .then(a => a.map(d => d.name))
        )
        .subscribe(
            names => console.log("NAME", names),
            err => console.log(err),
            () => console.log('done')
        );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.min.js"></script>

    这是#2,如果你想早期从Promise转换为Observable:

    Rx.Observable
        .fromPromise(
            fakeFetch('/names')
            .then(res => res.json())
        )
        .map(a => a.map(d => d.name)) // <====
        .subscribe(
            names => console.log("NAME", names),
            err => console.log(err),
            () => console.log('done')
        );
    

    直播示例:

    function fakeFetch() {
        return new Promise(resolve => {
            setTimeout(resolve, 100,
            		{
                	json: function() {
                     return JSON.parse('[' +
                        '{' +
                            '"name": "Jason",' +
                            '"age": 42' +
                        '},' +
                        '{' +
                            '"name": "Neely",' +
                            '"age": 41' +
                        '},' +
                        '{' +
                            '"name": "Tristan",' +
                            '"age": 21' +
                        '}' +
                    ']');
                  }
                }
            );
        });
    }
    Rx.Observable
        .fromPromise(
            fakeFetch('/names')
            .then(res => res.json())
        )
        .map(a => a.map(d => d.name)) // <====
        .subscribe(
            names => console.log("NAME", names),
            err => console.log(err),
            () => console.log('done')
        );
    <script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.min.js"></script>

答案 1 :(得分:1)

承诺正在返回一个数组,所以在.fromPromise之后你想要.flatMap'展开'数组,可以这么说。

Rx.Observable.fromPromise(
  fetch('https://jsonplaceholder.typicode.com/users')
    .then(res => res.json())
)
.flatMap(x => x)
.map(x => x.name)
.subscribe(console.log)
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/5.5.2/Rx.js"></script>