Во-первых, я извиняюсь за рудиментарный вопрос, но я провел дни, читая об асинхронных функциях, и еще не нашел решения или не понял. Я обещаю, что если мне помогут, я заплачу позже здесь.
У меня есть набор операций или задач, которые я должен выполнять по одной за раз. Первая задача — запустить, затем вторая, третья.
Проблема в следующем:
Для всех задач выполнить случайное число x операций записи в папку. Каждое задание нужно выполнять до завершения, а затем переходить к следующему заданию.
Задание 1: Войдите в консоль, когда начнете писать файл Task1_1. Когда файл будет записан, зарегистрируйте «Завершенная запись Task1_1». Перемещайтесь к Task1_1+1, пока не дойдете до Task1_X.
Задача 2: Пишите все задачи в одно и то же «время». Завершите запись всех файлов, прежде чем переходить к следующей задаче.
Задача 3: 30% файлов должны быть записаны в неверный путь. Если он записан по неверному пути, напишите «Не удалось записать файл Task3_X», в противном случае следуйте тому же шаблону, что и в задаче 1.
Я пытался использовать Async и await, я пробовал традиционные обратные вызовы. Меня больше всего устраивают обещания, но мне явно не хватает ключевого концептуального понимания того, что происходит (если это вас беспокоит... извините... люди были суровы в отношении моего уровня здесь... просто пытаюсь учиться).
function writeFileAsync(directory, file){
return new Promise( (resolve,reject) => {
console.info(`Writing File ${file}`)
fs.writeFile(path.join(directory,file), 'this is a file', (err) => {
if (err){
reject(err)
} else{
resolve()
}
})
})
}
function taskOne(x, location){
return new Promise(resolve => {
console.info('** Starting task taskOne **')
let i = 1;
while(i <= x){
let name = `taskOne_${i}`;
writeFileAsync(location,name)
.then(logCompletion(name))
.then(i++)
}
console.info('** Finished with taskOne **')
})
}
function taskTwo(x, location){
return new Promise(resolve => {
console.info('** Starting task taskTwo **')
let i = 1;
while(i <= x){
let name = `taskTwo_${i}`;
writeFileAsync(location, name)
.then((success) => logCompletion(name))
.then(i++)
}
console.info(`** Finished with taskTwo **`)
})
}
function taskThree(x, location){
return new Promise( resolve => {
console.info('** Starting task taskThree **')
const badPath = path.join(__dirname,`/notHome`);
const randomlyDelayedIndex = Math.floor(Math.random()*Math.floor(x+1)+1);
const isItGoodOrBad = () => {
let chance = Math.floor(Math.random()*Math.floor(10)+1)
return chance < 7 ? true : false
}
let i = 1;
while(i <= x){
let name = `taskThree_${i}`;
let directionIsGood = isItGoodOrBad();
if (directionIsGood){
debugger
writeFileAsync(location, name)
.then(logCompletion(name))
.then(i++)
} else{
writeFileAsync(badPath, name)
.then((success)=> logCompletion(name))
.catch((err) => console.info(`Failed to write ${name}`))
.then(i++)
}
}
console.info(`** Finished with taskThree **`)
})
}
function main(){
const folderName = String(Date.now());
const x = Number(folderName.slice(-1));
const location = path.join(__dirname,folderName);
fs.mkdir(location, ()=> {});
return taskOne(7, location)
.then(taskTwo(7,location))
.then(taskThree(7,location))
}
main();
Я ожидаю (может измениться ритм в зависимости от случайности):
Starting Task1
Writing Task1_1
Finished Task1_1
Writing Task1_2
Finished Task1_2
etc....
Finished with Task1
Starting Task2
Writing Task2_1
Writing Task2_2
Writing Task2_2
etc...
Finished Task2_1
Finished Task2_2
Finished Task2_3
etc...
Finished with Task2
Starting Task3
Writing Task3_1
Failed to Write Task3_1
Writing Task3_2
Finished Writing Task3_2
Writing Task3_3
Finished Writing Task3_3
Finished Task3
Я получаю что-то вроде этого:
** Starting task taskOne **
Writing File taskOne_1
Finished Writing file taskOne_1
Writing File taskOne_2
Finished Writing file taskOne_2
Writing File taskOne_3
Finished Writing file taskOne_3
Writing File taskOne_4
Finished Writing file taskOne_4
Writing File taskOne_5
Finished Writing file taskOne_5
Writing File taskOne_6
Finished Writing file taskOne_6
Writing File taskOne_7
Finished Writing file taskOne_7
** Finished with taskOne **
** Starting task taskTwo **
Writing File taskTwo_1
Writing File taskTwo_2
Writing File taskTwo_3
Writing File taskTwo_4
Writing File taskTwo_5
Writing File taskTwo_6
Writing File taskTwo_7
** Finished with taskTwo **
** Starting task taskThree **
Writing File taskThree_1
Finished Writing file taskThree_1
Writing File taskThree_2
Writing File taskThree_3
Writing File taskThree_4
Finished Writing file taskThree_4
Writing File taskThree_5
Finished Writing file taskThree_5
Writing File taskThree_6
Writing File taskThree_7
Finished Writing file taskThree_7
** Finished with taskThree **
Failed to write taskThree_2
Failed to write taskThree_3
Failed to write taskThree_6
Finished Writing file taskTwo_1
Finished Writing file taskTwo_2
Finished Writing file taskTwo_3
Finished Writing file taskTwo_6
Finished Writing file taskTwo_7
Finished Writing file taskTwo_4
Вам нужно сопоставить ваши файловые операции с серией промисов, а затем использовать Promise.all
Примечание не по теме: невежество приветствуется в Stack Overflow. Концептуальное понимание — вот почему люди приходят сюда в первую очередь. Что нас раздражает, так это то, что люди ожидают, что мы решим за них все их задачи, в то время как они не прилагают никаких усилий (как правило, путем копирования и вставки своих заданий). Также несколько утомительно (но в гораздо меньшей степени), когда люди публикуют вопросы с недостаточной детализацией. SO — прекрасное место, но мы ожидаем, что вы будете вести себя так, как будто это настоящие люди делают это для своего собственного образования и отдыха на другом конце, а не рабы, выполняющие ваши приказы. Ты справишься.
Вы смешиваете синхронный и асинхронный код. Например, вы можете переписать свой taskOne
следующим образом:
const writeFileAsync = () => {
return Promise.resolve();
};
const logCompletion = (n) => {
console.info(n);
return Promise.resolve();
};
async function taskOne(x, location){
console.info('** Starting task taskOne **')
let i = 1;
while(i <= x){
let name = `taskOne_${i}`;
await writeFileAsync(location,name)
.then(logCompletion(name))
.then(i++)
}
console.info('** Finished! with taskOne **')
}
async function taskTwo(x, location){
console.info('** Starting task taskTwo **')
let i = 1;
while(i <= x){
let name = `taskTwo_${i}`;
await writeFileAsync(location,name)
.then(logCompletion(name))
.then(i++)
}
console.info('** Finished with taskTwo **')
}
taskOne(12).then(() => taskTwo(12));
Вы можете посмотреть пример здесь: https://codepen.io/anon/pen/KLBwby
Я думаю, вы должны быть в состоянии выяснить остальное.
Спасибо Вован! Поэтому, когда я пишу функцию для записи файла, это будет: , ()=> {}) resolve(); reject(err); }) } ?
Ваша текущая функция writeFileAsync
в порядке. Я просто выпотрошил его здесь, поскольку Codepen не работает на Node (он работает в браузере), и я хотел продемонстрировать что-то работающее в Интернете. Если вы просто используете свой, он должен работать нормально. Хитрость заключается в том, как вы используете асинхронный и Ждите. await
сигнализирует вызывающему коду о приостановке выполнения функций до завершения асинхронной операции...
Круто, можешь отчитаться, если возникнут проблемы.
Ооооо мой looordddd спасибо !!! Сейчас я буду работать над третьей задачей. Серьезно .. Я знаю, что кто-то задавал этот вопрос, но я искал вверх и вниз. Я обещаю, что ваш ответ поможет многим людям. Спасибо большое. Серьезно!
Круто, рад, что у тебя получилось. К вашему сведению, это описано здесь: Developers.google.com/web/fundamentals/primers/promises Однако я могу понять, что, пока вы только изучаете это, может быть трудно разобраться в приложениях. Удачи!
У меня есть вопрос - я думаю, что это корень одного из моих недоразумений - у меня есть следующий код: async function taskTwo(x, location){ ..... (вспомогательная функция, которая возвращает обещание) await runTheFile() console .log(** Finished with taskTwo **
) } почему я не получаю этот журнал консоли? Я также пробовал это с .then(console.info) и .then(() => console.info)
Нам, вероятно, лучше обсудить это в чате, так как это выходит за рамки вопроса.
writeFileAsync
возвращает обещание, но вы никогда нигде не используете эти обещания