繁体   English   中英

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

[英]How to wait for javascript promise to return value before continuing execution?

我编写了一个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承诺执行各种操作。 我编写了一个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:我需要这种同步行为,因为类中有多个子/嵌套/子组件将调用此类通用函数。

这是您要在哪里使用async / await的完美示例

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

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

可以在此处找到带有示例的详细指南。

doSomething函数存在一些问题:

doSomething(param1, param2) {
  this._vendor.domSomething(param1 + param2);
    .then(retVal => {
      return {retVal};
    });
};
  1. 不应使用分号“;” 在“ .then”方法之前。
  2. 您执行的功能应该返回promise,您不能从“ then”块返回值。

考虑稍微改变一下功能:

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

这样,在您的异步“单击”函数中,您将可以使用await来返回承诺:

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
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM