在继续执行之前,如何等待javascript承诺返回值?
我已经编写了一个util类,它是基于承诺的供应商库的包装器。我的应用程序将调用这个类(在应用程序和操作中)来执行某些操作 我目前正在处理一个场景,在继续下一步之前,我的代码需要知道Util类中promise的返回值。我该怎么做 以下是我的代码的树结构:在继续执行之前,如何等待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 │
├── 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};
});
};
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};
});
};
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中时