У меня возникла некоторая основная проблема с JS Promises.Вот мой полный код
'use strict'
const rp = require('request-promise');
const cheerio = require('cheerio');
var fs = require('fs');
var os = require('os');
const options = {
uri: url,
normalizeWhitespace: true,
transform: function (body) {
return cheerio.load(body);
}
};
let results = []
let results2 = []
rp(options)
.then(($) => {
$('.col-xs-4 .grid-item').each(function (i, elem) {
let temp = $(this).find(".prod-image").attr("style")
let productImageUrl = temp.substring(temp.indexOf("background-image:url('") + 22, temp.indexOf("')"))
let detailUrl = $(this).find(".prod-image").attr("href")
let title = $(this).find(".title").text()
let description = $(elem).children().eq(4).attr("content")
results.push({
"productImageUrl": productImageUrl,
"detailUrl": detailUrl,
"title": title,
"description": description
})
});
})
.then(() => {
results.forEach(item => {
const options1 = {
uri: item.detailUrl,
normalizeWhitespace: true,
transform: function (body) {
return cheerio.load(body);
}
};
rp(options1)
.then(($) => {
console.log(5)
let temp = $('#prod-title').text()
let unit = temp.substring(temp.indexOf('Size: ') + 6, temp.indexOf('mL') - 1)
let retail = temp.substring(temp.indexOf('Retail: $') + 9, temp.indexOf(' A'))
let wholesale = temp.substring(temp.indexOf('Wholesale: $') + 12, temp.indexOf(' A') + 21)
results2.push({
"productImageUrl": item.productImageUrl,
"detailUrl": item.detailUrl,
"title": item.title,
"description": item.description,
"unit": unit,
"retail": retail,
"wholesale": wholesale
})
})
.catch((err) => {
console.log(err);
});
})
})
.finally(() => {
console.log("FINALLY " + results2)
let header = "Handle,Title,Body" + os.EOL
fs.writeFile("./file.csv", header, function (err) {
if (err) {
return console.log(err);
}
});
for (let item of results2) {
console.log(2)
let hyphenateTitle = item.title.replace(/\s+/g, '-').toLowerCase();
let line = hyphenateTitle + "," + item.title + "," + item.description + "," + vendor + ',"","",true,Title,Default Title,,,,,SKU,10000,,1,deny,manual,' + item.retail + "," + item.wholesale + "," + 'true,true,"",' + item.productImageUrl + "," + ',1,,false,,,,,,,,,,,,,,,,,kg,' + os.EOL
fs.appendFile("./file.csv", line, function (err) {
if (err) {
return console.log(err);
} else {
// done
}
})
}
})
.catch((err) => {
console.log(err);
});
Идея состоит в том, что в первом then()
я прочитаю HTML-страницу и найду несколько URL-адресов.Я перенесу эту информацию в массив results
.
Затем на втором then
идея состоит в том, чтобы перебрать каждый элемент массива и перейти на вторую страницу, извлечь дополнительную информацию и отправить ее.на results
Finally
, получите всю эту информацию в формате CSV.
Это вывод в консоли:
FINALLY
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
5
Итак, как вы можете видетьпоследний then
работает до среднего (но после самого верхнего.
Что я делаю не так? Спасибо
РЕДАКТИРОВАТЬ 1 Это новый кодкак предложил один из комментаторов:
'use strict'
const rp = require('request-promise');
const cheerio = require('cheerio');
var fs = require('fs');
var os = require('os');
const options = {
uri: url,
normalizeWhitespace: true,
transform: function (body) {
return cheerio.load(body);
}
};
let results = []
let results2 = []
rp(options)
.then(($) => {
console.log("FIRST THEN")
$('.col-xs-4 .grid-item').each(function (i, elem) {
let temp = $(this).find(".prod-image").attr("style")
let productImageUrl = temp.substring(temp.indexOf("background-image:url('") + 22, temp.indexOf("')"))
let detailUrl = $(this).find(".prod-image").attr("href")
let title = $(this).find(".title").text()
let description = $(elem).children().eq(4).attr("content")
results.push({
"productImageUrl": productImageUrl,
"detailUrl": detailUrl,
"title": title,
"description": description
})
});
})
.then(($) => {
console.log("SECOND THEN")
return Promise.all(results.map( item => {
console.log("SECOND THEN INNER")
const options1 = {
uri: item.detailUrl,
normalizeWhitespace: true,
transform: function (body) {
return cheerio.load(body);
}
};
rp(options1)
.then(($) => {
console.log("SECOND THEN INSIDE 'rp(options1)'")
let temp = $('#prod-title').text()
let unit = temp.substring(temp.indexOf('Size: ') + 6, temp.indexOf('mL') - 1)
let retail = temp.substring(temp.indexOf('Retail: $') + 9, temp.indexOf(' A'))
let wholesale = temp.substring(temp.indexOf('Wholesale: $') + 12, temp.indexOf(' A') + 21)
results2.push({
"productImageUrl": item.productImageUrl,
"detailUrl": item.detailUrl,
"title": item.title,
"description": item.description,
"unit": unit,
"retail": retail,
"wholesale": wholesale
})
})
.catch((err) => {
console.log(err);
});
}))
})
.finally(($) => {
console.log("FINALLY " + results2)
let header = "Handle,Title,Body" + os.EOL
fs.writeFile("./file.csv", header, function (err) {
if (err) {
return console.log(err);
}
});
for (let item of results2) {
console.log(2)
let hyphenateTitle = item.title.replace(/\s+/g, '-').toLowerCase();
let line = hyphenateTitle + "," + item.title + "," + item.description + "," + vendor + ',"","",true,Title,Default Title,,,,,SKU,10000,,1,deny,manual,' + item.retail + "," + item.wholesale + "," + 'true,true,"",' + item.productImageUrl + "," + ',1,,false,,,,,,,,,,,,,,,,,kg,' + os.EOL
fs.appendFile("./file.csv", line, function (err) {
if (err) {
return console.log(err);
} else {
// done
}
})
}
})
.catch((err) => {
console.log(err);
});
И это вывод:
FIRST THEN
SECOND THEN
SECOND THEN INNER
SECOND THEN INNER
SECOND THEN INNER
SECOND THEN INNER
SECOND THEN INNER
SECOND THEN INNER
SECOND THEN INNER
SECOND THEN INNER
SECOND THEN INNER
SECOND THEN INNER
SECOND THEN INNER
SECOND THEN INNER
SECOND THEN INNER
SECOND THEN INNER
SECOND THEN INNER
SECOND THEN INNER
SECOND THEN INNER
SECOND THEN INNER
SECOND THEN INNER
SECOND THEN INNER
SECOND THEN INNER
SECOND THEN INNER
SECOND THEN INNER
SECOND THEN INNER
FINALLY
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'
SECOND THEN INSIDE 'rp(options1)'