使用Promise.map返回与蓝鸟“订购”的对象

时间:2016-02-16 21:44:22

标签: javascript node.js promise bluebird

我有一个数字数组,我传递给 api url 。它返回一个对象的答案,但问题是我希望这个对象按照原始数组排序。

这是我的代码:

var Promise = require("bluebird");
var cheerio = require('cheerio');
var request = Promise.promisifyAll(require("request"));

var numbers = ['22222', '33333', '44444'];
var obj = {};

Promise.map(numbers, function(number) {
    var options = {
        url: 'http://example.com/api',
        method: 'POST',
        form: {'number': number}
    };
    return request.postAsync(options).spread(function(response, body){
        if (response.statusCode == 200){
            var $ = cheerio.load(body);
            var link = $('script').get()[5].children[0].data;
            var regexNumber = new RegExp('<strong><h1>(.*?)</h1></strong>');
            var result = (regexNumber.exec(link)[1]);
            obj[number] = result;
        }
        else {
            console.log('Error');
        }
    });
}, {concurrency: 1}).then(function() {
    console.dir(obj);
});

这就是抛出:

{ '33333': 'a text',
  '44444': 'a text',
  '22222': 'a text' }

我想这样:(根据原始数组的顺序)

{ '22222': 'a text',
  '33333': 'a text',
  '44444': 'a text' }

我也尝试过这个其他代码,同样的事情发生了:

var numbers = ['22222', '33333', '44444'];
var obj = {
    number: [],
    text:
};

var links = numbers.each(function(number) {
    var options = {
        url: 'http://example.com/api',
        method: 'POST',
        form: {'number': number}
    };
    return request.postAsync(options).spread(function(response, body){
        if (response.statusCode == 200){
            var $ = cheerio.load(body);
            var link = $('script').get()[5].children[0].data;
            var regexNumber = new RegExp('<strong><h1>(.*?)</h1></strong>');
            var result = (regexNumber.exec(link)[1]);
            obj.number.push(number);
            obj.text.push(result);
            return obj;
        }
        else {
            console.log('Error');
        }
    });
});

Promise.all(links).then(function(results) {
    results.forEach(function (data, i){
        console.log(i + ' => ' + data.number[i] + ' => ' + data.text[i]);
    });
});

一些想法?

1 个答案:

答案 0 :(得分:3)

您应该使用mapSeries,按顺序迭代您的收藏(map并不保证,毕竟是并行)。

var numbers = ['22222', '33333', '44444'];

Promise.mapSeries(numbers, function(number) {
    return request.postAsync({
        url: 'http://example.com/api',
        method: 'POST',
        form: {'number': number}
    }).spread(function(response, body){
        if (response.statusCode == 200){
            var $ = cheerio.load(body);
            var link = $('script').get()[5].children[0].data;
            var regexNumber = new RegExp('<strong><h1>(.*?)</h1></strong>');
            return regexNumber.exec(link)[1];
        } else {
            console.log('Error'); // throw it?
        }
    });
}).then(function(results) {
    for (var i=0; i<results.length; i++)
       console.log(i + ' => ' + numbers[i] + ' => ' + results[i]);
});