use*_*875 4 javascript promise ecmascript-6 es6-promise
我有一个用于验证字符串的方法,我希望该方法返回一个 Promise,因为正在运行的验证可能是异步的。然而,我遇到的问题是性能之一,我希望承诺尽可能在同一个事件循环中解决(例如:当没有异步验证需要完成时),但我希望接口保持一致(例如:始终返回一个 Promise)。
下面的简化代码示例说明了我正在尝试执行的操作,但它会导致上述性能损失,因为即使可以同步执行验证,它仍然会等待下一个事件循环来处理结果。
在我的具体用例中,这种性能损失太高了。
下面是我正在做的事情的简化(最小)示例
// Array containing validation methods
const validations = [
(value) => true, // Some validation would happen here
];
// Array containing asynchronous validation methods
const asyncValidations = []; // No async validations (but there could be)
const validate(value){
// Run synchronous validations
try {
validations.forEach(validation => validation(value));
catch(error){
// Synchronous validation failed
return Promise.reject();
}
if(asyncValidations){
return Promise.all(asyncValidations.map(validation => validation(value));
}
// Otherwise return a resolved promise (to provide a consistent interface)
return Promise.resolve(); // Synchronous validation passed
}
// Example call
validate('test').then(() => {
// Always asynchronously called
});
Run Code Online (Sandbox Code Playgroud)
You mention two different things:
I want the interface to remain consistent
[I want to] always return a Promise
If you want to avoid the asynchronous behaviour if it is not needed, you can do that and keep the API consistent. But what you cannot do is to "always return a Promise" as it is not possible to "resolve a promise synchronously".
Your code currently returns a Promise that is resolved when there is no need for an async validation:
// Otherwise return a resolved promise (to provide a consistent interface)
return Promise.resolve(); // Synchronous validation passed
Run Code Online (Sandbox Code Playgroud)
You can replace that code with the following:
return {then: cb => cb()};
Run Code Online (Sandbox Code Playgroud)
Note that this just returns an object literal that is "thenable" (i.e. it has a then method) and will synchronously execute whatever callback you pass it to. However, it does not return a promise.
You could also extend this approach by implementing the optional onRejected parameter of the then method and/or the the catch method.