在同步项目中正确使用Promise

时间:2017-06-25 05:39:52

标签: javascript asynchronous promise

我有一个标准的JavaScript项目。它主要与几个回调同步。我需要使用第三方库来简化操作。问题是这个库基于异步方法和Promises。我以前从未真正使用过这种方法。

我有一种情况,我只需要something = get_info();代码都非常模块化,因此堆叠了多个函数调用。问题是get_info是异步的。我无法弄清楚如何使用这个异步函数来处理我的项目,而不必重写整个事情。

编辑:以下是类似代码的示例

function my_class() {
    this.do_something( data ) {
        if ( this.get_data() == data ) {
            do_the_thing();
        }
    }

    this.get_data = function() {
        return library.get_info( arguments ); //can't do this, returns a promise
    }
}

var stuff = new my_class();

for ( var i = 0; i < len; i++ ) {
    stuff.do_something( i )
}

同样,目标是不重写应用程序的整个部分。想法?

2 个答案:

答案 0 :(得分:0)

没有需要宣传链中调用的每个函数。您可以在promise的链中尽可能多地调用同步或异步函数。您需要考虑的是等待已解决的价值的地方。

您的代码距离工作不远,只需添加.then()块就可以了。

下面的工作示例:

function my_class() {
  this.do_something(data) {
    //Call the promise-returning function
    this.get_data()
      .then((resolvedData) => {
        //Wait for promise resolution
        //and compare the resolved value to 'data'
        if (resolvedData === data) {
          do_the_thing();
        }
      })
      .catch();
  }

  this.get_data = () => {
    return library.get_info(arguments);
  }
}

var stuff = new my_class();

for (var i = 0; i < len; i++) {
  stuff.do_something(i)
}

它是如何运作的?

  1. do_something(i)被称为
  2. this.get_data()函数内部调用
  3. do_something()
  4. get_data()返回的承诺已经解决时,执行将继续进行.then()阻止。
  5. resolvedDataget_data()承诺的解析值。
  6. 比较值,然后继续。
  7. 正如您所看到的,即使对stuff.do_something(i)的调用尚未完成,也不会考虑for循环将继续。

    在你的问题中不清楚你是否允许它们全部并行运行(如现在),或者如果你需要它们按顺序运行。

    如果您想知道是否所有通话都已完成,您可以让do_something()返回承诺,然后等待所有人使用Promise.all()解决,如下所示

    function my_class() {
      this.do_something(data) {
        //Call the promise-returning function
        //Note that we return the same promise - no need to create a new one!
        return this.get_data()
          .then((resolvedData) => {
            //Wait for promise resolution
            //and compare the resolved value to 'data'
            if (resolvedData === data) {
              do_the_thing();
            }
          })
          .catch();
      }
    
      this.get_data = () => {
        return library.get_info(arguments);
      }
    }
    
    var stuff = new my_class();
    //
    var promises = [];
    for (var i = 0; i < len; i++) {
      //Push each promise to the array
      promises.push(stuff.do_something(i));
    }
    
    Promise.all(promises)
      .then(() => {
        console.log("All promises have been resolved!")
      })
      .catch(() => {
        //Handle errors
      });
    

答案 1 :(得分:-1)

TextView

您需要宣传链中涉及的每个功能.. 像这样......

不确定完整的方案,代码看起来像这样。