使用 http.get node.js 的承诺

新手上路,请多包涵

我正在做 nodeschool 练习,

这个问题和前面的问题(HTTP COLLECT)一样,都需要用到http.get()。但是,这次您将获得三个 URL 作为前三个命令行参数。

您必须收集每个 URL 提供给您的完整内容,并将其打印到控制台 (stdout)。您不需要打印出长度,只需打印出字符串形式的数据即可;每个 URL 一行。问题是您必须按照与作为命令行参数提供给您的 URL 相同的顺序打印它们。

换句话说,我要注册 3 个 http.get 请求,并按顺序打印从中收到的数据。

我正在尝试使用 promises = 另一个获取请求不会被调用,直到第一个请求没有结束。

我的代码看起来像这样

var http=require("http");
var collect=[];
var dat=[];
for( var i = 2 ; i < process.argv.length;i++){
    collect.push(process.argv[i]);
}

function chainIt(array,callback){
    return array.reduce(function(promise,item){
        return promise.then(function(){
            return callback(item)
        })
    },Promise.resolve())
}

function getIt(item){
    return http.get(item,function(response){
        response.on("data",function(data){
                dat.push(data);
        })

    })
}

chainIt(collett,function(item){
    return getIt(item)
    })
}).then(function(){
    collect.forEach(function(x){
            console.log(x);
    })

})

但我实际上没有打印任何数据 = 我没有通过练习。

我在这里没有看到任何错误,但我只是从承诺和节点开始。错误在哪里?

原文由 Johnyb 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 546
1 个回答

出于教育目的,我最近为 httphttps 模块编写了一个包装器,该模块使用原生 Promise s。也就是说,我建议使用一个库,例如 request ;这使事情变得更简单,具有单元测试覆盖率,由开源社区维护。此外,我的包装器对响应块进行了简单的字符串连接,我不认为这是构建响应主体的最佳方式。

仅供参考:这需要 Node.js 4 或更高版本,尽管方法在 Node 0.xx 中几乎相同

'use strict';

const http = require('http');
const url = require('url');

module.exports = {
    get(url) {
        return this._makeRequest('GET', url);
    },

    _makeRequest(method, urlString, options) {

        // create a new Promise
        return new Promise((resolve, reject) => {

            /* Node's URL library allows us to create a
             * URL object from our request string, so we can build
             * our request for http.get */
            const parsedUrl = url.parse(urlString);

            const requestOptions = this._createOptions(method, parsedUrl);
            const request = http.get(requestOptions, res => this._onResponse(res, resolve, reject));

            /* if there's an error, then reject the Promise
             * (can be handled with Promise.prototype.catch) */
            request.on('error', reject);

            request.end();
        });
    },

    // the options that are required by http.get
    _createOptions(method, url) {
        return  requestOptions = {
            hostname: url.hostname,
            path: url.path,
            port: url.port,
            method
        };
    },

    /* once http.get returns a response, build it and
     * resolve or reject the Promise */
    _onResponse(response, resolve, reject) {
        const hasResponseFailed = response.status >= 400;
        var responseBody = '';

        if (hasResponseFailed) {
            reject(`Request to ${response.url} failed with HTTP ${response.status}`);
        }

        /* the response stream's (an instance of Stream) current data. See:
         * https://nodejs.org/api/stream.html#stream_event_data */
        response.on('data', chunk => responseBody += chunk.toString());

        // once all the data has been read, resolve the Promise
        response.on('end', () => resolve(responseBody));
    }
};

编辑: 我才刚刚意识到你是 Promise 的新手。以下是如何使用此包装器的示例:

 'use strict';

const httpService = require('./httpService'); // the above wrapper

// get one URL
httpService.get('https://ron-swanson-quotes.herokuapp.com/v2/quotes').then(function gotData(data) {
    console.log(data);
});

// get multiple URLs
const urls = [
    'https://ron-swanson-quotes.herokuapp.com/v2/quotes',
    'http://api.icndb.com/jokes/random'
];

/* map the URLs to Promises. This will actually start the
 * requests, but Promise.prototype.then is always called,
 * even if the operation has resolved */
const promises = urls.map(url => httpService.get(url));

Promise.all(promises).then(function gotData(responses) {
    /* responses is an array containing the result of each
     * Promise. This is ordered by the order of the URLs in the
     * urls array */

    const swansonQuote = responses[0];
    const chuckNorrisQuote = responses[1];

    console.log(swansonQuote);
    console.log(chuckNorrisQuote);
});

原文由 James Wright 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题