Request-promise API调用未按React app中的预期更新变量

时间:2017-11-30 03:22:21

标签: javascript request-promise

我在React app中有以下IIFE:

const GetFeedData = (function () {
    let feed, feedId;
    return {
        getFeedId: function (sub) {
            switch (sub) {
                case '1': case '2': case '3': case '4': case '5': case '6': case 'S':
                    feedId = 1;
                    break;
                case 'A': case 'C': case 'E':
                    feedId = 26;
                    break;
                case 'N': case 'Q': case 'R': case 'W':
                    feedId = 16;
                    break;
                case 'B': case 'D': case 'F': case 'M':
                    feedId = 21;
                    break;
                case 'L':
                    feedId = 2;
                    break;
                case 'G':
                    feedId = 31;
                    break;
            }
        },
        getFeedData: function () {
            rp({
                method: 'GET',
                url: 'https://cors-anywhere.herokuapp.com/http://datamine.mta.info/mta_esi.php?key=MY_KEY&feed_id=' + feedId,
                encoding: null
            }).then((buf) => {
                feed = GtfsRealtimeBindings.transit_realtime.FeedMessage.decode(buf);
            });
        },
        get feed() { return feed; }
    };
})();

正如您所看到的,getFeedData应该更新feed变量,该变量稍后将被称为GetFeedData上的属性。现在,当我的代码稍后调用该变量时,它会以undefined出现并导致其余的脚本失败。

我在以下代码中替换了getFeedData来测试这是否会影响结果:

getFeedData: function () {
        if (feedId === 2) {
            feed = require('./MockData');
        }

当我将'L'作为sub参数传递时,让getFeedData中的条件返回true(使用其中一个下拉菜单进行的过程)组件),我不再得到TypeError说feed未定义。我假设这意味着我的问题出在API调用中?任何人都可以告诉我这听起来是否正确以及我可以采取哪些措施来解决问题?

1 个答案:

答案 0 :(得分:0)

您无法直接引用由异步函数设置值的变量,因为您将遇到返回值undefined的不一致性。

但是,您可以通过Promise直接从feed方法返回getFeedData变量:

const GetFeedData = (function() {

    // more code here...

    return {
        GetFeedData: () => {
            return new Promise((resolve, reject) => {
                rp({
                    method: 'GET',
                    url: 'https://cors-anywhere.herokuapp.com/http://datamine.mta.info/mta_esi.php?key=MY_KEY&feed_id=' + feedId,
                    encoding: null
                }).then((buf) => {
                    feed = GtfsRealtimeBindings.transit_realtime.FeedMessage.decode(buf);
                    resolve(feed)
                }).catch(_ => reject())
            })
        },
    }
})()

// Use it like this
GetFeedData.GetFeedData().then((feed) => {
    console.log(feed)
})