连续承诺未解决

时间:2020-04-04 01:33:58

标签: javascript node.js asynchronous async-await es6-promise

我正在一个项目中,在该项目中我使用一些promise / timeout来延迟不同功能的调用 这个项目的代码有点大..所以我认为最好对其做一个示例并进行测试,然后找出导致诺言(仅最后一个)无法解决的原因。 在对这些代码进行了示例之后,再次发生了与我相同的错误,所以当我知道我的逻辑中有什么问题并想要寻求帮助时,它就出现了。

我将在下面编写代码并在之后进行解释:

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应该导致测试函数能够解析,但不能解析。.

任何帮助将不胜枚举! :)

1 个答案:

答案 0 :(得分:1)

现在,在else的情况下,您有一个悬空的承诺未与其他任何东西连接:

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

当前运行的 test函数在递归调用之后再也不会调用其res,因此它永远都无法解析,因此对

的初始调用

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

从不导致final运行。

虽然您可以通过添加test(data.i).then(res)来修复它,以确保Promises都已连接:

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

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();
});

每当有一个Promise时,几乎都应该return,或者将其作为脚本的初始异步操作。