javascript - Change async workflow to Promise (Bluebird) -
i have been trying wrap head around promises. basic concepts understand, once gets nested, little bit confused. feedback appreciated
here code trying refactor promises (bluebird)
var getindividualdata = function(url, donegetindividualdata) { var $, data; request(url, function(err, res, body) { if (!err && res.statuscode === 200) { $ = cheerio.load(body); data = { title: $("#itemtitle").children()["0"].next.data, condition: $("#vi-itm-cond").text(), price: $("#prcisum_bidprice").text(), imgurl: $("#icimg")[0].attribs.src, createdat: chance.date(), likes: chance.integer({min: 0, max: 1000}) }; donegetindividualdata(null, data); } else { donegetindividualdata(err); } }); }; var getlisting = function(url, donegetlisting) { var $; var links = []; request(url, function(err, res, body) { if (!err && res.statuscode === 200) { $ = cheerio.load(body); $('.vip').each(function(i, el) { if (i < 15) { links.push(el.attribs.href); } }); async .concat(links, getindividualdata, function(err, result) { return donegetlisting(null, result); }); } else { donegetlisting(err); } }); }; var puttomongo = function(err, result) { if (devconfig.seeddb) { mongoose.connect(devconfig.mongo.uri); item.find({}).remove(function(err, items) { item.create(result, function(err, items) { console.log('done'); process.kill(); }); }); } }; async .concat(urls, getlisting, puttomongo);
the first thing wrap request
in returns promise. many promise libraries have utilities "promisifying" async functions, don't think that'll work here because request
passes 2 success values callback:
var requestasync = function(url) { return new promise(function (resolve, reject) { request(function (err, res, body) { if (err) { reject(err); } resolve({ res: res, body: body}); }); }); };
once that's done, gets lot easier:
var getindividualdata = function(url) { return requestasync(url).then(function (result) { if (result.res.statuscode === 200) { var $ = cheerio.load(result.body); return { title: $("#itemtitle").children()["0"].next.data, condition: $("#vi-itm-cond").text(), price: $("#prcisum_bidprice").text(), imgurl: $("#icimg")[0].attribs.src, createdat: chance.date(), likes: chance.integer({min: 0, max: 1000}) }; } throw new error("individual data status code: " + result.res.statuscode); }); }; var getlisting = function(url, donegetlisting) { return requestasync(url).then(function (result) { if (result.res.statuscode === 200) { var $ = cheerio.load(result.body), promises = $('.vip').filter(function (i) { return < 15; }).map(function (i, el) { return getindividualdata(el.attribs.href); }); return promise.all(promises); } throw new error("listing status code: " + result.res.statuscode); }); }; var puttomongo = function(result) { if (devconfig.seeddb) { mongoose.connect(devconfig.mongo.uri); item.find({}).remove(function(err, items) { item.create(result, function(err, items) { console.log('done'); process.kill(); }); }); } }; promise.all(urls.map(getlisting)) .then(puttomongo) .catch(function (err) { // handle error });
Comments
Post a Comment