我一直试图绕着Promises。对于我理解的基本概念,但一旦嵌套,我有点困惑。任何反馈都表示赞赏
这是我试图重构为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);
答案 0 :(得分:2)
首先要做的是将request
包装在返回promise的内容中。许多承诺图书馆都有实用工具,用于宣传&#34;异步函数,但我不认为它会在这里工作,因为request
将两个成功值传递给它的回调:
var requestAsync = function(url) {
return new Promise(function (resolve, reject) {
request(function (err, res, body) {
if (err) {
reject(err);
}
resolve({ res: res, body: body});
});
});
};
一旦完成,就会变得容易多了:
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 i < 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
});