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

在继续执行之前,如何等待javascript承诺返回值?,javascript,node.js,reactjs,promise,es6-promise,Javascript,Node.js,Reactjs,Promise,Es6 Promise,我已经编写了一个util类,它是基于承诺的供应商库的包装器。我的应用程序将调用这个类(在应用程序和操作中)来执行某些操作 我目前正在处理一个场景,在继续下一步之前,我的代码需要知道Util类中promise的返回值。我该怎么做 以下是我的代码的树结构: ├── index.html ├── package-lock.json ├── package.json ├── scripts │   ├── vendor_script.min.js ├── src │   ├── actions │  

我已经编写了一个util类,它是基于承诺的供应商库的包装器。我的应用程序将调用这个类(在应用程序和操作中)来执行某些操作

我目前正在处理一个场景,在继续下一步之前,我的代码需要知道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

app.js

import React,{Component}来自'React';
从“../common/js/VendorUtils”导入{VendorUtils};
导出默认类应用程序扩展组件{
点击(){
让utilsInstance=VendorUtils.getInstance();
设x=utilsInstance.doSomething('a','b');
设y=utilsInstance.doSomethingElse(x,'a');
//使用前面步骤中接收到的值调用操作
}
render(){
返回(
点击我!
点击我!
点击我!
);
}
}

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

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


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


您可以找到一个包含示例的详细指南。

这是一个完美的示例,说明了您希望在哪里使用
async
/
wait

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

这是一个完美的示例,说明了您希望在何处使用
async
/
wait

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

剂量测量功能存在一些问题:

doSomething(param1, param2) {
  this._vendor.domSomething(param1 + param2);
    .then(retVal => {
      return {retVal};
    });
};
  • 不应该有分号“;”before“。then”方法
  • do something函数应该返回承诺,但不能从“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};
        });
    };
    
    这样,在异步“单击”函数中,您就可以使用Wait for returned Promission:

    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
    }
    

    剂量测量功能存在一些问题:

    doSomething(param1, param2) {
      this._vendor.domSomething(param1 + param2);
        .then(retVal => {
          return {retVal};
        });
    };
    
  • 不应该有分号“;”before“。then”方法
  • do something函数应该返回承诺,但不能从“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};
        });
    };
    
    这样,在异步“单击”函数中,您就可以使用Wait for returned Promission:

    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
    }
    


    。然后
    不为您工作?@Sag1v
    。然后
    将创建一个承诺,该承诺将在每次执行时进行评估,但此时调用函数已经转移到下一行代码。因此,x的值将是未定义的。需要该值的下一行应位于
    块内。您可以使用async/await,但这只是幕后的承诺和生成器。@RahilParikh不创建承诺链是不可能的。在承诺得到解决之前,您无法阻止,您只能将稍后应该执行的所有代码放入
    然后
    回调中(或在
    等待
    之后)@RahilParikh:您缺少的是,一旦您的函数对承诺执行了一些异步工作,那么使用该函数的任何东西都必须是异步的。你不能混合使用sync和async
    。那么
    对你不起作用?@Sag1v
    。那么
    将创建一个承诺,该承诺将在每次执行时进行评估,但此时调用函数已经移动到下一行代码。因此,x的值将是未定义的。需要该值的下一行应位于
    块内。您可以使用async/await,但这只是幕后的承诺和生成器。@RahilParikh不创建承诺链是不可能的。在承诺得到解决之前,您无法阻止,您只能将稍后应该执行的所有代码放入
    然后
    回调中(或在
    等待
    之后)@RahilParikh:您缺少的是,一旦您的函数对承诺执行了一些异步工作,那么使用该函数的任何东西都必须是异步的。你不能混合使用sync和async。我尝试了你建议的解决方案,但当我在
    单击的
    doSomething
    中添加
    语句时,我注意到JavaScript首先从
    单击的
    中打印
    x
    的值(这是
    未定义的
    )然后打印返回值
    retVal
    ,该值来自
    doSomething
    (即
    ab
    )。请注意,
    中的代码。然后,
    是一个长时间运行的任务,有时可能需要4/5秒。@RahilParikh您得到了
    未定义的
    ,因为您仍然没有找到问题的最重要的一点,您正在等待未定义的,因为您没有在“做某事”函数中返回承诺,请看我的答案。@RahilParikh如Nik所述,您似乎没有从
    doSomething
    函数内部返回承诺。修复这些调用,您会发现这段代码按预期工作。这本身是不够的。OP必须修复它们的
    doSomething()
    doSomethingElse()
    方法才能正常工作。@jfriend00已经在评论中指出,问题更多的是如何在后续的承诺中使用一个承诺的结果。我尝试了您建议的解决方案,但当我将
    console.log
    语句放入
    单击的
    doSom中时