【发布时间】:2019-11-25 19:30:54
【问题描述】:
我在这里的措辞上有点挣扎,但要点是我使用了一个返回对象的 Promise.race(如下所示)。大多数时候,至少有几个 Promise 会崩溃,但这是故意的。这只是意味着没有找到产品。为了避免 promise 返回空白,我使用 try catch 块来启动 15 秒的新定时 promise。这可以防止 Promise 返回空白,让正确完成的最快函数将其对象返回到 Promise.race。在使用 Windows 10 在 NodeJS 10 中进行测试时,这似乎工作得很好,但是当我将它移植到运行 NodeJS 8 和 Ubuntu 18.04 的 Linux 服务器时,我得到了一些奇怪的行为。 Promise.race 工作得非常好,直到我在启动 NodeJS 应用程序后第一次测试该功能以来已经过去了 15 秒。当这 15 秒过去后,当我尝试与正常承诺竞争时,它会立即返回定时承诺。
我首先要兑现这些承诺。 (不确定是否重要,但这是通过 HTTP 请求调用的)
let product = await Promise.race([
get_info_meny_joker(bar_code, "meny.no"),
get_info_meny_joker(bar_code, "joker.no"),
get_info_openfoodfacts(bar_code)
])
其中一个看起来像这样
async function get_info_meny_joker(bar_code, link) {
try {
let url = 'https://' + link + '/Sok/?query=' + bar_code
let browser = await puppeteer.launch({args: ['--no-sandbox']})
let page = await browser.newPage()
await page.goto(url, { waitUntil: 'networkidle2' })
let get_link = await page.evaluate(() => document.querySelector('.ws-product__title').getAttribute('href') )
let product_name = await page.evaluate(() => document.querySelector('.ws-product__title').innerText )
let product_amount = await page.evaluate(() => document.querySelector('.ws-product__subtitle').innerText )
let regex = "[0-9]+([gl]+|ml| [gl] | ml |kg| kg)"
let match = product_amount.match(regex)
match = match[0]
/*let regex_index = new RegExp("[A-Za-z]")
let index_match = regex_index.exec(match).index
match = match.splice(index_match, 0, " ")*/
product_amount = match
await page.goto('https://' + link + '/' + get_link, { waitUntil: 'networkidle2' })
const [first_product, second_product] = await page.$$('.ws-collapsable-block__heading');
await page.screenshot({ path: "x.png" })
second_product.click()
await page.screenshot({ path: "y.png" })
let img_url = await page.evaluate(() => document.querySelector('.lazyloaded').attributes[1].value)
// Get a list of all the nutrients found on the page
let nutrients_raw = await page.evaluate(() => {
let nutrients_raw = document.querySelector('.ws-nutritional-content').children
let nutrients = {}
let i = 0
for (let item of nutrients_raw) {
nutrients[i + ""] = item.innerText
i++
}
return nutrients
});
// Pretify the nutrients_raw to a nutrients object
let nutrients = {}
for (let i = 0; i < Object.size(nutrients_raw); i++) {
let s = nutrients_raw[i]
let type = s.slice(0, s.indexOf(':'))
let amount = s.slice(s.indexOf(':') + 2, s.length)
nutrients[type] = amount
}
return new Product(bar_code, product_name, product_amount, img_url, nutrients, link)
} catch (err) {
return await promise
}
}
定时承诺是这样的
let promise = new Promise((resolve, reject) => {
let product = new Product()
product.name = "Could not be located"
setTimeout(() => resolve(product), 15000)
});
重复我自己,我可以 Promise.race 并且它工作得非常好,直到我第一次参加比赛以来已经过去了 15 秒。
(对这个问题并不重要,但我将 Promise.race 函数理解为从堆栈中完全删除丢失的 Promise。奇怪的是它记得 15 秒过去了。)
【问题讨论】:
标签: javascript node.js promise