Последовательные обещания не разрешаются - PullRequest
0 голосов
/ 04 апреля 2020

Я работаю над проектом, в котором я использую некоторые обещания / тайм-аут для задержки вызова различных функций, код этого проекта немного велик ... поэтому я подумал, что может быть лучше сделать образец этого и протестировать это и найти причину, которая заставляет обещание (только последнее) не решить. После создания примера этого кода снова возникла та же ошибка, что и со мной, поэтому я понял, что в моей логике что-то не так, c и хотел обратиться за помощью:

Я буду напишите код ниже и объясните его после:

let i = 0; // delaring i wich help us recall the test method (until a given length)

//function 1 2 and 3 are 3 functions that take few seconds to resolve ( made it simpler for you guys 
// to understand my problem


function function1() {
  return new Promise((res, rej) => {
    setTimeout(() => {
      console.log("from function 1");
      res();
    }, 1000);
  });
}

function function2() {
  return new Promise((res, rej) => {
    setTimeout(() => {
      console.log("from function 2");
      res();
    }, 1000);
  });
}
//in function 3 if the i didnt reach the length given ( made static here=10) it will finish its code
// then call the test method with the new/incremented i
// this keep happening until i= the required length(10) where the function will return true
// and when the function 3 return back true.. the test function should resolve and call the final()
// function

function function3(i) {
  return new Promise((res, rej) => {
    setTimeout(() => {
      console.log("from function 3");
      if (i + 1 == 10) {
        res({ bool: true });
      } else {
        i++;
        res({ bool: false, i: i });
      }
    }, 2000);
  });
}

function final() {
  console.log("final");
}

function test(i) {
  return new Promise((res, rej) => {
    function1().then((data) => {
      function2().then((data) => {
        function3(i).then((data) => {
          console.log("boolean: ", data.bool);
          if (data.bool) {
            console.log("true..so if");
             res();
          } else {
            console.log("false..so else");
            test(data.i);
          }
        });
      });
    });
  }); //end of promise
}

test(i).then(() => {
  final();
});

код работает хорошо и печатает несколько раз подряд: из функции 1 из функции 2 из функции 3 .... и вот где должна вызываться последняя функция выведите «final», но его нет во время отладки. Я заметил, что функция 3 возвращает назад значение «false» 9 раз, и значение true в последнем случае, и это значение «true» должно вызывать разрешение тестовой функции, но это не так.

any помощь будет очень полезна! :)

1 Ответ

1 голос
/ 04 апреля 2020

Прямо сейчас, в случае else, у вас есть висящее Обещание , не связанное ни с чем другим:

      } else {
        console.log("false..so else");
        test(data.i);
      }

, запущенный в данный момент У функции test никогда не вызывается res после рекурсивного вызова, поэтому она остается неразрешенной навсегда, поэтому первоначальный вызов

test(i).then(() => {
  final();
});

никогда не приводит к выполнению final.

Хотя вы можете исправить это, добавив test(data.i).then(res), чтобы убедиться, что все Обещания подключены:

let i = 0; // delaring i wich help us recall the test method (until a given length)

//function 1 2 and 3 are 3 functions that take few seconds to resolve ( made it simpler for you guys 
// to understand my problem


function function1() {
  return new Promise((res, rej) => {
    setTimeout(() => {
      console.log("from function 1");
      res();
    }, 100);
  });
}

function function2() {
  return new Promise((res, rej) => {
    setTimeout(() => {
      console.log("from function 2");
      res();
    }, 100);
  });
}
//in function 3 if the i didnt reach the length given ( made static here=10) it will finish its code
// then call the test method with the new/incremented i
// this keep happening until i= the required length(10) where the function will return true
// and when the function 3 return back true.. the test function should resolve and call the final()
// function

function function3(i) {
  return new Promise((res, rej) => {
    setTimeout(() => {
      console.log("from function 3");
      if (i + 1 == 10) {
        res({ bool: true });
      } else {
        i++;
        res({ bool: false, i: i });
      }
    }, 200);
  });
}

function final() {
  console.log("final");
}

function test(i) {
  return new Promise((res, rej) => {
    function1().then((data) => {
      function2().then((data) => {
        function3(i).then((data) => {
          console.log("boolean: ", data.bool);
          if (data.bool) {
            console.log("true..so if");
            return res();
          } else {
            console.log("false..so else");
            test(data.i).then(res);
          }
        });
      });
    });
  }); //end of promise
}

test(i).then(() => {
  final();
});

Было бы намного лучше избегать явного создания паттерна Promise и избегать паттерна Promise-as-callback. Это можно сделать кратко, сделав test и async функцию:

async function test(i) {
  await function1();
  await function2();
  const data = await function3(i);
  console.log("boolean: ", data.bool);
  if (data.bool) {
    console.log("true..so if");
    return;
  } else {
    console.log("false..so else");
    await test(data.i);
  }
}

let i = 0; // delaring i wich help us recall the test method (until a given length)

//function 1 2 and 3 are 3 functions that take few seconds to resolve ( made it simpler for you guys 
// to understand my problem


function function1() {
  return new Promise((res, rej) => {
    setTimeout(() => {
      console.log("from function 1");
      res();
    }, 100);
  });
}

function function2() {
  return new Promise((res, rej) => {
    setTimeout(() => {
      console.log("from function 2");
      res();
    }, 100);
  });
}
//in function 3 if the i didnt reach the length given ( made static here=10) it will finish its code
// then call the test method with the new/incremented i
// this keep happening until i= the required length(10) where the function will return true
// and when the function 3 return back true.. the test function should resolve and call the final()
// function

function function3(i) {
  return new Promise((res, rej) => {
    setTimeout(() => {
      console.log("from function 3");
      if (i + 1 == 10) {
        res({ bool: true });
      } else {
        i++;
        res({ bool: false, i: i });
      }
    }, 200);
  });
}

function final() {
  console.log("final");
}

async function test(i) {
  await function1();
  await function2();
  const data = await function3(i);
  console.log("boolean: ", data.bool);
  if (data.bool) {
    console.log("true..so if");
    return;
  } else {
    console.log("false..so else");
    await test(data.i);
  }
}
test(i).then(() => {
  final();
});

Или, если вам нужно продолжать использовать .then s:

function test(i) {
  return function1()
    .then(function2)
    .then(() => function3(i))
    .then((data) => {
      console.log("boolean: ", data.bool);
      if (data.bool) {
        console.log("true..so if");
        return;
      } else {
        console.log("false..so else");
        return test(data.i);
      }
    });
}

let i = 0; // delaring i wich help us recall the test method (until a given length)

//function 1 2 and 3 are 3 functions that take few seconds to resolve ( made it simpler for you guys 
// to understand my problem


function function1() {
  return new Promise((res, rej) => {
    setTimeout(() => {
      console.log("from function 1");
      res();
    }, 100);
  });
}

function function2() {
  return new Promise((res, rej) => {
    setTimeout(() => {
      console.log("from function 2");
      res();
    }, 100);
  });
}
//in function 3 if the i didnt reach the length given ( made static here=10) it will finish its code
// then call the test method with the new/incremented i
// this keep happening until i= the required length(10) where the function will return true
// and when the function 3 return back true.. the test function should resolve and call the final()
// function

function function3(i) {
  return new Promise((res, rej) => {
    setTimeout(() => {
      console.log("from function 3");
      if (i + 1 == 10) {
        res({ bool: true });
      } else {
        i++;
        res({ bool: false, i: i });
      }
    }, 200);
  });
}

function final() {
  console.log("final");
}

function test(i) {
  return function1()
    .then(function2)
    .then(() => function3(i))
    .then((data) => {
      console.log("boolean: ", data.bool);
      if (data.bool) {
        console.log("true..so if");
        return;
      } else {
        console.log("false..so else");
        return test(data.i);
      }
    });
}
test(i).then(() => {
  final();
});

Всякий раз, когда у вас есть Обещание, вы должны почти всегда return выполнять его или выполнять начальную асинхронную операцию сценария.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...