【问题标题】:How to use promise in while(JavaScript/Node.js)?如何在 while(JavaScript/Node.js) 中使用 Promise?
【发布时间】:2019-11-09 17:05:42
【问题描述】:

我正在尝试使用 promise 和 while (JavaScript/Node.js) 依次重复执行多个进程。 但是,promise 函数没有被执行(即所有的 console.log() 都不会显示)。

为什么promise函数在while中从来没有执行过?

另外,如何按顺序重复显示一些console.log()?

var count = 0;
while(count < 5) {
  Promise.resolve()
  .then(function () {
    return new Promise(function(resolve, reject) {
      console.log('func1()...');
      resolve('OK');
    });
  })
  .then(function(value) {
    return new Promise(function(resolve, reject) {
      console.log('func2()...');
      resolve('OK');
    });
  })
  .then(function (value) {
    console.log('func3()...');
    count++;
  }).catch(function (error) {
    console.log(error);
  });
}

【问题讨论】:

  • 您的count++; 异步执行,您的while 只是永远循环。
  • 你不能。查看 Promise.all 或 async/await 语法。
  • @tkausl promise函数是通过在promise函数后面写count++来执行的。谢谢你。但是,每个console.log()都会连续执行5次。我想这样跑。 console.log(func1()...)→console.log(func2()...)→console.log(func3()...)→console.log(func1()...)→.. .

标签: javascript node.js loops synchronous


【解决方案1】:

.then() 仍然是一个异步回调,看这里的消息顺序:

Promise.resolve().then(()=>console.log("got resolved"));
console.log("got here");

您可以做的一件事是将代码包装到async function

async function test(){
  var count = 0;
  while(count < 5) {
    await Promise.resolve()
    .then(function () {
      return new Promise(function(resolve, reject) {
        console.log('func1()...');
        resolve('OK');
      });
    })
    .then(function(value) {
      return new Promise(function(resolve, reject) {
        console.log('func2()...');
        resolve('OK');
      });
    })
    .then(function (value) {
      console.log('func3()...');
      count++;
    }).catch(function (error) {
      console.log(error);
    });
  }
}

test();

【讨论】:

    【解决方案2】:

    发生了什么 - 在 Javascript 中,您编写的事件循环和源代码在一个线程中执行。这意味着如果这个线程被某些工作阻塞,则不会执行其他任何操作。 它的工作原理非常简单 - 事件循环接受一个事件(您显示的代码)并处理所有同步部分,并将任何异步事物(承诺链)推送到事件循环以供稍后执行。

    问题是这样的:

    var count = 0;
    while(count < 5) {
      Promise.resolve()
      .then(
      // some promise chain...
    }
    

    while 被捕获在永无止境的循环中,因为所有同步部分都是它将这个 Promise 链推送到事件循环中,然后重新开始。在这种情况下,count 永远不会改变。

    最适合你的是使用async/await,它可以完全解决你想要的,而不需要深入了解Node.js

    另一种选择是使用递归

    function promiseChain() {
      return Promise.resolve()
      .then(function () {
        return new Promise(function(resolve, reject) {
          console.log('func1()...');
          resolve('OK');
        });
      })
      .then(function(value) {
        return new Promise(function(resolve, reject) {
          console.log('func2()...');
          resolve('OK');
        });
      })
      .then(function (value) {
        console.log('func3()...');
        count++;
      }).catch(function (error) {
        console.log(error);
      });
    }
    
    recursivelyExecute(promise, count) {
      if (count > 5) {
        return;
      }
      count++;
      return promise.then(() => recursivelyExecute(promiseChain(), count+1));
    }
    

    【讨论】:

    • 非常感谢您的提议。但是,此代码在 recursivelyExecute (promise, count) {} 中给出错误。 (错误:意外的令牌 { )为什么?
    • 此代码可能需要进行一些清理。如果这只是示例代码,则将“count”用作作为 arg 传递的阴影变量会令人困惑,如果是可执行代码,则会被破坏。
    【解决方案3】:

    var count = 0;
    while(count < 5) {
      Promise.resolve()
      .then(function () {
        return new Promise(function(resolve, reject) {
          console.log('func1()...');
          resolve('OK');
        });
      })
      .then(function(value) {
        return new Promise(function(resolve, reject) {
          console.log('func2()...');
          resolve('OK');
        });
      })
      .then(function (value) {
        console.log('func3()...');
      }).catch(function (error) {
        console.log(error);
      });
      count++;
    }

    【讨论】:

    • 谢谢,promise函数执行完毕。但是,每个console.log()都会连续执行5次。我想这样跑。 console.log (func1 () ...) → console.log (func2 () ...) → console.log (func3 () ...) → console.log (func1 () ...) → .. .
    【解决方案4】:

    您需要使用Promise.all()async.eachSeries 进行循环。为此,您需要安装async,然后执行以下操作:

    const async = require('async');
    var count = [...Array(5).keys()];
    async.eachSeries(count, (c, next) => {
      Promise.all([
        new Promise(function (resolve, reject) {
          console.log('func1()...');
          resolve('OK');
        }), 
        new Promise(function (resolve, reject) {
          console.log('func2()...');
          resolve('OK');
        })]).then(function (values) {
        console.log('func3()...');
        next();
      });
    }, (err) => {
      console.log("here we done");
    });
    

    【讨论】:

    • 谢谢,几乎是我想要的答案。但是结果如下:console.log('func1()...')→console.log('func2()...')→console.log('func3()...')→ console.log('func3()...')→console.log('func3()...')→...我想做如下:console.log('func1()...' )→console.log('func2()...')→console.log('func3()...')→console.log('func1()...')→console.log('func2 ()...')→console.log('func3()...')→...
    • 我看到你找到了答案。我刚刚修复了它并更新了我的答案,以供将来寻找解决方案的人使用。
    猜你喜欢
    • 2013-05-26
    • 2014-04-16
    • 2016-05-04
    • 2018-09-28
    • 2014-05-05
    • 2019-02-13
    • 2013-10-07
    • 1970-01-01
    • 2021-06-03
    相关资源
    最近更新 更多