Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 时间承诺解决在之前一次使用时间解决后立即返回_Javascript_Node.js_Promise - Fatal编程技术网

Javascript 时间承诺解决在之前一次使用时间解决后立即返回

Javascript 时间承诺解决在之前一次使用时间解决后立即返回,javascript,node.js,promise,Javascript,Node.js,Promise,我在这里的措辞上有点纠结,但要点是我使用了一个Promise.race来返回一个对象(如下所示)。在大多数情况下,至少有一些承诺会崩溃,但这是故意的。这只是意味着没有找到产品。为了避免承诺返回空白,我使用try-catch块启动一个新的15秒定时承诺。这可以防止promise返回空白,让正确完成的最快函数将其对象返回到promise.race。当使用Windows 10在NodeJS 10中进行测试时,这似乎工作得很好,但当我将其移植到运行NodeJS 8和Ubuntu 18.04的Linux服

我在这里的措辞上有点纠结,但要点是我使用了一个Promise.race来返回一个对象(如下所示)。在大多数情况下,至少有一些承诺会崩溃,但这是故意的。这只是意味着没有找到产品。为了避免承诺返回空白,我使用try-catch块启动一个新的15秒定时承诺。这可以防止promise返回空白,让正确完成的最快函数将其对象返回到promise.race。当使用Windows 10在NodeJS 10中进行测试时,这似乎工作得很好,但当我将其移植到运行NodeJS 8和Ubuntu 18.04的Linux服务器时,我发现了一些奇怪的行为。在启动NodeJS应用程序后,我第一次测试了这个函数,直到15秒后,Promise.race才完全正常工作。当这15秒过去后,当我尝试去实现正常的承诺时,它会立即返回定时承诺

我从兑现这些承诺开始。(不确定这是否重要,但这是通过HTTP请求调用的)

其中一个看起来像这样

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)
});
重复一遍,我可以保证。比赛,它工作得非常好,从我第一次参加比赛到现在已经过去了15秒


(这对问题并不重要,但我理解Promise.race函数是从堆栈中完全删除丢失的承诺。奇怪的是,它记住15秒已经过去了。)

您需要在以下情况下创建一个新的
承诺:

let promise = new Promise((resolve, reject) => {
    let product = new Product()
    product.name = "Could not be located"
    setTimeout(() => resolve(product), 15000)
});
每次你想用它的时候。否则,当您开始使用计时器时,计时器已经运行了一段时间,它将在远低于15000毫秒的时间内启动,因为它已经运行了一段时间。事实上,如果创建承诺后的时间超过15000ms,那么它将已经解决,当您在
.race()
中使用它时,比赛将立即以这个已经解决的承诺结束

这个问题并不重要,但我理解Promise.race函数是从堆栈中完全删除丢失的承诺。奇怪的是,它记得15秒已经过去了

这是不对的
Promise.race()
不会删除任何内容。任何输掉比赛的承诺都会很顺利。只是,
promise.race()
返回的承诺将在比赛中的第一个承诺完成后立即得到解决。其他人继续做得很好,并将按照自己的时间表完成


可能您想要做的是将其放入一个函数并调用该函数,只要您想要15000毫秒的承诺:

function timeoutPromise(t) {
    return new Promise(resolve => {
        let product = new Product();
        product.name = "Could not be located";
        setTimeout(() => resolve(product), t);
    });
}
然后,您不必使用已经保存的
promise
变量,只要调用此函数,就可以在需要使用新的超时承诺时获得新的承诺

function timeoutPromise(t) {
    return new Promise(resolve => {
        let product = new Product();
        product.name = "Could not be located";
        setTimeout(() => resolve(product), t);
    });
}