【问题标题】:Promise function in separate file单独文件中的承诺功能
【发布时间】:2017-08-29 04:33:16
【问题描述】:

我可以让这个函数在一个文件中工作,但我想通过分成多个文件来保持干净。

// library.js file
module.exports = {
    get: () =>{
        return new Promise((reject, resolve) =>{
            return resolve(https.get('https://api.instagram.com/v1/users/self/?access_token=' + cred.access_token, (res) =>{
                res.setEncoding('utf8');
                return res.on('data', (data) =>{
                    return data;
                });
            }));
        });
    }
}

我尝试记录此内容,但没有显示任何内容?

// server.js file
igLib.get().then((data) => {
    console.log("testing: " + data);
})

但是,如果我只是做一个简单的日志......

// server.js file
console.log(igLib.get());

我以某种方式获得了没有res.setEncoding('utf8') 的数据。

有什么建议吗?

更新: 我无法得到工作的承诺,我很抱歉那些为我的问题提供了很好答案的人,但我继续使用 request-promise 模块。看起来是这样的:

// library.js file
var instagramSelfUrl = 'https://api.instagram.com/v1/users/self/?access_token=' + cred.access_token;

module.exports = {
    get: () =>{
        return rp(instagramSelfUrl).then((res) =>{
            return res;
        });
    }
}

这是我 console.log 的地方:

// server.js file
    igLib.get().then((data) =>{
    console.log(data);
});

它更简单并且有效。如果除了使用模块之外还有解决问题的方法,请告知并发布!感谢所有发帖和帮助的人!

【问题讨论】:

  • 单独的文件!嗯,为什么不使用 js 类呢
  • @user889030 文件和类有什么关系?!
  • 您的问题是您立即使用来自https.get(即undefined)的返回值解决您的承诺,而不是使用异步回调中的data 解决

标签: javascript express promise


【解决方案1】:

您创建的承诺应该使用响应中的数据来解决。

// library.js file
const https = require('https');
const instagramSelfUrl = 'https://api.instagram.com/v1/users/self/?access_token=' + cred.access_token;

module.exports = {
    get: () => new Promise(function (resolve, reject) {
        https.get(instagramSelfUrl, res => {
            var chunks = [];
            res.setEncoding('utf8');
            res.on('data', chunk => chunks.push(chunk));
            res.on('end', () => resolve(chunks.join('')));
        });
    })
};

事实上,以上内容是不完整且脆弱的。例如,请求错误或响应状态 500 应该拒绝承诺,但没有错误处理。或者当响应不是真正的 UTF-8 时,它会不正确地解码数据。这些只是这里最明显的两个问题。

HTTP 请求的承诺是一个已解决的问题。我强烈建议您使用one of the available libraries,而不是滚动您自己的代码,这会再次犯所有错误。

const request = require('request-promise');
const instagramSelfUrl = 'https://api.instagram.com/v1/users/self/?access_token=' + cred.access_token;

module.exports = {
    get: () => request(instagramSelfUrl)
};

现在该功能已完成并且运行正常,即使在极端情况下也是如此。它也很短,几乎没有理由编写一个单独的函数。

【讨论】:

  • 我没有意识到您可以将我们作为回电解决。我会测试一下,谢谢。是的,我明白这个功能有多脆弱:仍在尝试承诺 =\
  • function (x) { f(x) } 和它的胖箭头表亲x => f(x) 在语义上等同于ffresolve 还是任何其他函数都没有区别。这只是相互调用的函数。在大多数情况下,创建一个除了包装另一个函数之外什么都不做的函数是多余的。
  • 我仍然无法让 promise 工作,但我决定继续使用 request-promise 模块。是的,我明白,我只是没有意识到您可以完全用 resolve 替换回调函数。最终无法让它工作。不过谢谢!
  • @Edrich 是的,https 模块如此低级,您实际上需要处理单独到达的数据块。请参阅更改的答案。我自己忘记了,这证明了我的观点。滚动你自己的 HTTP 库是不值得的。
【解决方案2】:

看来你没有正确返回数据试试这个:

// library.js file
module.exports = {
    get: () =>{
        return new Promise((reject, resolve) =>{
            https.get('https://api.instagram.com/v1/users/self/?access_token=' + cred.access_token, (res) =>{
                res.setEncoding('utf8');
                return res.on('data', (data) =>{
                    return resolve(data);
                });
            });
        });
    }
}

【讨论】:

  • 不需要return 来自onresolve 的结果。
  • 实际上我之前也尝试过,但在这种情况下我的 console.log 甚至都没有受到影响。
【解决方案3】:

你可以这样做

module.exports = {
    get: () =>{
        return new Promise((resolve, reject) =>{
            https.get('https://api.instagram.com/v1/users/self/?access_token=' + cred.access_token, (res) =>{
                res.setEncoding('utf8');
                res.on('data', (data) =>{
                    resolve(data);
                });
            }).on('error', (e) => reject(e))
        });
    }
}

有关承诺的更多信息,您可以访问https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Promise

【讨论】:

  • 我已经尝试过了,但我的 console.log 甚至没有在其他文件中被命中。
猜你喜欢
  • 1970-01-01
  • 2017-10-18
  • 2020-12-14
  • 2023-04-01
  • 2018-04-19
  • 1970-01-01
  • 1970-01-01
  • 2018-03-31
  • 1970-01-01
相关资源
最近更新 更多