Как заставить мою программу продолжать работать, когда одно обещание разрешается или отклоняется? - PullRequest
0 голосов
/ 08 февраля 2020

Я хочу, чтобы моя программа разрешала, если все работало, а затем go к следующему тесту, используя цикл for; или, если есть ошибка, я хочу, чтобы она снова запустилась. Но если она выдаст ошибку шесть раз, я хочу, чтобы она отказалась и попробовала следующую функцию с l oop.

Что я ожидаю:

index is 0 and loop is 0
index is 1 and loop is 0
index is 2 and loop is 0
index is 3 and loop is 0
index is 4 and loop is 0
index is 5 and loop is 0
5 is too many errors
[printed error]
index is 0 and loop is 7
index is 1 and loop is 7
index is 2 and loop is 7
index is 3 and loop is 7
index is 4 and loop is 7
index is 5 and loop is 7
5 is too many errors
[printed error] ..  and so on

Что я на самом деле получаю :

index is 0 and loop is 0
index is 1 and loop is 0
index is 2 and loop is 0
index is 3 and loop is 0
index is 4 and loop is 0
index is 5 and loop is 0
5 is too many errors
(node:29808) UnhandledPromiseRejectionWarning: undefined
(node:29808) UnhandledPromiseRejectionWarning: Unhandled promise rejection.

Код:

const hello = async (index, i) => {
  return new Promise(async (resolve, reject) => {
        console.log(`index is ${index} and loop is ${i}`)
        if(index === 5){
            reject(console.log(`${index} is too many errors`)) // this runs
        } else if (index === 6){
            resolve(console.log("I realize it won't ever resolve :) ")) 
        }
        else{
            hello(++index, i)
        }
    })
};

const loop_function = async () => {
    return new Promise (async(res, rej)=>{
        for (var i = 0; i <= 35; i += 7) {
            try{
                await hello(0, i)
            } catch(err){
                console.log("caught an error!") // this does not run
            }
        }
        res(console.log("resolved everything")) // this does not run
    })
}


const final = async () =>{
    await loop_function()
    console.log("loop_function complete") // this does not run
}


final();

Ответы [ 2 ]

3 голосов
/ 08 февраля 2020

Что нужно изменить:

  1. очистить new Promise() оболочки от обеих функций; они не нужны, поскольку функции AsyncFunctions гарантированно возвращают Promise, а внутри вы можете просто вернуть / выбросить.
  2. обязательно наберите return hello(++index, i), чтобы вернуть результат каждого уровня рекурсии на его более высокие уровни и, в конечном итоге, исходному абоненту на самом верхнем уровне.
  3. при выполнении условия (index >= 5) просто выведите Error; нет необходимости регистрироваться, так как блок catch вызывающего (loop_function's) будет выполнять регистрацию.

Итак, вы можете получить:

const hello = async (index, i) => {
	console.log(`index is ${index} and loop is ${i}`);
	if(index >= 5) {
		throw new Error(`${index} is too many errors`);
	} else {
		return hello(++index, i);
	}
};
const loop_function = async () => {
	for (var i = 0; i <= 35; i += 7) {
		try {
			await hello(0, i);
		} catch(err) {
			console.log(err.message);
		}
	}
	console.log("resolved everything");
}
const final = async () =>{
	await loop_function();
	console.log("loop_function complete");
}
final();
1 голос
/ 08 февраля 2020

Проблема в том, что ваш рекурсивный вызов hello(++index, i) игнорируется - вы никогда не используете его значение результата. Это может быть отклоненное обещание (за которое вы получите предупреждение «необработанное отклонение»), и, что еще хуже, вы никогда не разрешите построенное обещание. Но вы все равно должны избегать конструктора Promise antipattern !

async function hello(index, i) {
    console.log(`index is ${index} and loop is ${i}`)
    if (index === 5) {
        throw new Error(`${index} is too many errors`)
    } else if (index === 6) {
        return "I realize it won't ever resolve :)"
    } else {
        return hello(++index, i)
//      ^^^^^^ this is essential! Or at least `await` the returned promise
    }
}

async function loop() {
    for (var i = 0; i <= 35; i += 7) {
        try {
            await hello(0, i)
        } catch(err) {
            console.log("caught an error!", err)
        }
    }
    console.log("resolved everything")
}

loop().then(() => {
    console.log("loop_function complete")
}, () => {
    console.log("unhandled error")
})
...