连续的承诺没有解决

Consecutive promises not resolving

我正在做一个项目,我使用一些 promises/timeout 来延迟不同函数的调用。

这个项目的代码有点大,所以我想做一个样本并测试它可能会更好,找到导致承诺(只有最后一个)无法解决的原因。

在制作了这段代码的示例之后,发生在我身上的同样的错误再次出现,所以当我知道我的逻辑有问题并想寻求帮助时:

我会在下面写代码,然后再解释:

let i = 0; // declaring i which 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 didn't 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 函数来打印“final”的地方,但事实并非如此。 调试时,我注意到函数 3 return 返回 false 9 次,最后一次返回 true,这个 true 应该会导致测试函数解析,但它不是。

现在,在 else 的情况下,您有一个 悬而未决的 Promise 没有连接到任何其他东西:

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

目前运行test函数在递归调用后从未调用过它的res,所以它永远没有解决,所以

的初始呼叫
test(i).then(() => {
  final();
});

永远不会导致 final 运行。

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

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

或者,如果您必须继续使用 .thens:

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 它,或者是脚本的初始异步操作。