如何等待javascript承诺在继续执行之前返回值?

时间:2017-11-11 09:00:26

标签: javascript node.js reactjs promise es6-promise

我编写了一个util类,它是基于promise的供应商库的包装器。我的应用程序将调用此类(在App& Actions中)来执行某些操作。

我目前正在处理一个场景,在继续下一步之前,我的代码需要知道Util类中promise的返回值。我怎么能这样做?

以下是我的代码的树结构:

├── index.html
├── package-lock.json
├── package.json
├── scripts
│   ├── vendor_script.min.js
├── src
│   ├── actions
│   │   └── index.js
│   ├── common
│   │   └── js
│   │       └── WrapperAroundVendorScript_Utils.js
│   ├── components
│   │   └── app.js
│   ├── index.js
│   └── reducers
│       └── index.js
├── style
│   └── style.css
├── webpack.config.js
├── yarn-error.log
└── yarn.lock

这里,vendor_script.min.js是供应商提供的JS库,它使用JS promises来执行各种操作。我编写了一个util类(WrapperAroundVendorScript_Utils.js)来抽象出供应商库的实现细节。

  

WrapperAroundVendorScript_Utils.js

let instance = null;

class VendorUtils {

  constructor (){

    const config = {
      some: value,
    }

    this._vendor = typeof window !== 'undefined' && window.vendor ? window.vendor : require([PATH]);
    this._vendor.config = config;
  };

  static getInstance() {
    if(typeof instance == "undefined" || !instance){
      instance = new VendorUtils();
    }
    return instance;
  }

  doSomething(param1, param2) {
    this._vendor.domSomething(param1 + param2);
      .then(retVal => {
        return {retVal};
      });
  };

  doSomethingElse(param1, param2) {
    this._vendor.domSomethingElse(param1 + param2);
      .then(retVal => {
        return {retVal};
      });
  };
}

module.exports.VendorUtils = VendorUtils;
  

app.js

import React, { Component } from 'react';
import {VendorUtils} from '../common/js/VendorUtils';

export default class App extends Component {

  clicked(){
    let utilsInstance = VendorUtils.getInstance();
    let x = utilsInstance.doSomething('a','b');
    let y = utilsInstance.doSomethingElse(x,'a');
    // call action with values received in previous steps
  }

  render() {
    return (
      <div>
        <button type='button' onClick={this.clicked}>Click Me!</button>
        <button type='button' onClick={this.clicked}>Click Me!</button>
        <button type='button' onClick={this.clicked}>Click Me!</button>
      </div>
    );
  }
}

PS:我需要这样的同步行为,因为类中有多个子/嵌套/子组件将调用这些常用函数。

3 个答案:

答案 0 :(得分:2)

这是您想要使用async / await

的完美示例
async clicked() {
  const utilsInstance = VendorUtils.getInstance();
  const x = await utilsInstance.doSomething('a','b');
  const y = await utilsInstance.doSomethingElse(x,'a');
  ...
}

答案 1 :(得分:0)

您可以执行您想要在您宣传的then子句内等待的代码,也可以使用Javascript的async / await功能。

可以找到详细的示例指南here

答案 2 :(得分:0)

您的doSomething功能存在一些问题:

doSomething(param1, param2) {
  this._vendor.domSomething(param1 + param2);
    .then(retVal => {
      return {retVal};
    });
};
  1. 不应该有分号&#34;;&#34;之前&#34; .then&#34;方法
  2. 你做某事函数应该返回承诺,你不能从&#34;然后&#34;返回一个值。块。
  3. 考虑改变你做某事的功能:

    doSomething(param1, param2) {
      // return the promise
      return this._vendor.domSomething(param1 + param2)
        // maybe you don't need this part at all if you want to get only the value instead of {retVal: value} object
        .then(retVal => {
          // if you do async operations here make sure you returned a new
          //   promise here instead of object, in that case you would need
          //   another .then block to process internal promise that you 
          //   would create inside this .then block 
          return {retVal};
        });
    };
    

    那样,在你的异步中#34;点击&#34;函数你可以使用等待返回的承诺:

    async clicked() {
      let utilsInstance = VendorUtils.getInstance();
    
      // you can check what doSomething returns here - it would be a promise
      let doSomethingPromise = utilsInstance.doSomething('a','b');
    
      // await a previously saved promise to get a value
      let x = await doSomethingPromise;
    
      // obviously you still can await promise in one sentence
      let y = await utilsInstance.doSomethingElse(x,'a');
    
      // call action with values received in previous steps
    }