使用默认参数调用异步函数作为参数检查处理同步的函数?

Posted

技术标签:

【中文标题】使用默认参数调用异步函数作为参数检查处理同步的函数?【英文标题】:Calling an async function with default parameter as function for arguments checking handled synchonous? 【发布时间】:2017-04-17 11:24:32 【问题描述】:

我在调用时使用异步函数和默认参数进行评估。

使用默认参数,我使用一个函数来检查是否提供了值。

function mandatory(paramName) 
    throw new Error(`Missing parameter: $paramName`)


async function foo( a, b = mandatory('b') ) 
    return Promise.resolve(b)


// uses chai.assert and chai-as-promised
describe('foo', () => 
    it('should return a rejected promise', async () => 
        const promise = foo( a: 'hi' )
        assert.isRejected(promise, /Error: Missing parameter: b/)
    )
)

此测试失败并出现错误:

Error: Missing parameter: b

因为您可以在此处看到此异常是在异步流之外引发的:

var foo = function () 
    var _ref = _asyncToGenerator(regeneratorRuntime.mark(function _callee(_ref2) 
        var _ref2$a = _ref2.a,
            a = _ref2$a === undefined ? 'a' : _ref2$a,
            _ref2$b = _ref2.b,
            b = _ref2$b === undefined ? mandatory('b') : _ref2$b;
        return regeneratorRuntime.wrap(function _callee$(_context) 
            while (1) 
                switch (_context.prev = _context.next) 
                    case 0:
                        return _context.abrupt('return', Promise.resolve(b));

                    case 1:
                    case 'end':
                        return _context.stop();
                
           
       , _callee, this);
    ));

    return function foo(_x) 
        return _ref.apply(this, arguments);
    ;
();

function _asyncToGenerator(fn)  
    return function ()  
         var gen = fn.apply(this, arguments); 
         return new Promise(function (resolve, reject)  
             function step(key, arg)  
                 try  
                     var info = gen[key](arg); 
                     var value = info.value; 
                  catch (error)  
                     reject(error); return; 
                  
                 if (info.done)  
                     resolve(value); 
                  else  
                     return Promise.resolve(value).then(function (value)  
                         step("next", value); 
                     , 
                     function (err)  
                         step("throw", err); 
                     ); 
                  
              
             return step("next"); 
         ); 
     ; 
 

我的问题:这是每个规范还是每个实现?我希望承诺会被拒绝,而不是被抛出。

【问题讨论】:

我想知道它是如何与async function foo( a, b = mandatory('b')) 反应的,参数是参数而不是对象属性。 参数评估发生在函数调用时。对async 函数的调用 本身是同步的。 异步函数是 ES 2017 草案的一部分,而不是 ES 7。 @bhantol 它的工作原理与我测试过的相同。例如。不像我预期的那样,而是抛出错误而不是被拒绝的承诺 【参考方案1】:

这可能是 Babel 中的一个错误,因为在最新的 Chrome(支持带有标志的异步函数)和 Firefox 52 中,此代码按预期工作(即承诺被拒绝):

function mandatory(paramName) 
  throw new Error(`Missing parameter: $paramName`)


async function foo( a, b = mandatory('b') ) 
  return Promise.resolve(b)


foo(a: 'hi').catch(error => console.log('rejected')) // logs 'rejected'

【讨论】:

s/可能/肯定/ @Bergi 我不确定,因为我不知道规范是怎么说的。 @Gothdo 如果规范中有其他内容,则应该修复它。要求对调用者进行双重错误检查似乎是不可接受的。

以上是关于使用默认参数调用异步函数作为参数检查处理同步的函数?的主要内容,如果未能解决你的问题,请参考以下文章

Spring boot:使用异步方法作为同步方法

异步回调函数

js执行顺序+同步异步

是否可以使用成员函数调用作为默认参数?

ajax 把返回结果作为参数传递

es6异步解决方案