【问题标题】:Execute long task in background using Promise使用 Promise 在后台执行长任务
【发布时间】:2017-11-12 23:55:57
【问题描述】:

在我的angular2 应用程序中,我有一个可能需要很长时间的方法,所以我使用promise 来异步执行它。 我希望计算在后台进行,因此 GUI 将继续照常工作,但我的 GUI 似乎在等待计算完成。

服务中的方法'func'-

return new Promise((resolve,reject) => {
            console.log("2");
            //some long process in database
            console.log("3");
            if(result!=null){
                resolve(result);
            }
            else{
                reject("Failure");
            }
}); 

我正在使用组件中的这个方法-

   this.service.func().then(data => {
            console.log("4");
   });
   console.log("done"); 

当前输出为 -
2
3
完成
4

期望的输出 -
完成
2
3
4

我错过了什么?如何使用promise 在后台执行长时间任务?

【问题讨论】:

    标签: typescript


    【解决方案1】:

    这个问题已经很久没有发布了,但这可能会对某人有所帮助。

    return new Promise((resolve, reject) => {
      console.log("2");
      //some long process in database
      console.log("3");
      if (result != null) {
        resolve(result);
      } else {
        reject("Failure");
      }
    });
    

    当前输出是 - 2 3 完毕 4

    期望的输出 - 完毕 2 3 4

    上面的代码没有给出想要的输出,因为 promise 构造函数中的代码是同步运行的。

    当 setImmediate() 如下使用时,它将打印所需的输出。 因为当使用 setImmediate() 或 setTimeout() 时,作为参数传递的函数将被放置在事件循环中执行。这样剩下的代码会首先执行,并且只有在事件循环中的任务队列空闲时,才会执行 setImmediate() 或 setTimeout()。

    return new Promise((resolve, reject) => {
      setImmediate(() => {
        console.log("2");
        //some long process in database
        console.log("3");
        if (result != null) {
          resolve(result);
        } else {
          reject("Failure");
        }
      });
    });
    

    【讨论】:

      【解决方案2】:

      您缺少的是在您的承诺中没有像 Web 服务调用这样的长时间运行的任务。因此,您的 Promise 会立即解析,这就是您按顺序看到控制台日志的原因。

      如果您想查看您正在寻找的行为,请使用 setTimeout 像这样在您的 Promise 中模拟一个长时间运行的任务。

      return new Promise((resolve,reject) => {
            // Simulate long running process with 2 second delay
            setTimeout(function () {
              console.log("2");
              console.log("3");
              resolve();
            }, 2000);
      }); 
      

      【讨论】:

      • 如果时间超过 2000 毫秒怎么办?
      • 延迟只是为了模拟 Web 服务调用等异步过程。在您的代码中,您将用您的 http 调用替换它。
      【解决方案3】:

      Promise 的内容本身不是异步的,Promise 将确保如果有像 http 请求这样的异步调用,它会在使用某些数据调用 resolve 时立即调用 then 回调函数。 但是如果你只是运行一个 console.log 它将同步运行。 尝试运行此代码以获得您的期望:

      return new Promise((resolve, reject) => {
              setTimeout(function() {
                console.log("2");
                console.log("3");
                resolve();
              }, 0);
        });
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-02-28
        • 2013-06-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多