原文:'returnawaitpromise'vs'returnpromise'inJavaScript结果可以等待promise执行完再返回awaitpromise,或者直接返回returnpromise:asyncfunctionfunc1(){constpromise=asyncOperation();returnawaitpromise;}//vsasync函数func2(){constpromise=asyncOperation();returnpromise;}您很快就会看到这两个表达式都可以有效地执行。但是,是否存在这些表达式表现不同的情况?让我们找出答案!1.Samebehavior(相同行为)为了找出这两个表达式(returnawaitpromise和returnpromise)的区别,会用到一个辅助函数promisedDivision(n1,n2)。此函数除以2个参数并返回包装在Promise中的结果:}else{returnPromise.resolve(n1/n2);如果第二个(除数)参数为0,该函数将返回一个拒绝的Promise,因为除以0是不可能的。好的,定义了辅助函数后,让我们对一些数字进行除法计算。以下函数divideWithAwait()使用returnawaitpromiseDivision(6,2)表达式返回用promise包装的6除以2的结果:asyncfunctiondivideWithAwait(){returnawaitpromisedDivision(6,2);}asyncfunctionrun(){const结果=awaitdivideWithAwait();控制台日志(结果);//记录3}run();在run()函数内部,等待divideWithAwait()返回结果,divideWithAwait()等待promisedDivision(6,2)执行后返回结果。一切正常。现在让我们尝试使用不带await关键字的第二个表达式,并直接返回包装除法结果的promiseReturnpromiseDivision(6,2):asyncfunctiondivideWithoutAwait(){returnpromisedDivision(6,2);}asyncfunctionrun(){constresult=awaitdivideWithoutAwait();控制台日志(结果);//记录3}run();即使在divideWithoutAwait()中没有使用await关键字,run()函数divideWithoutAwait()中的表达式仍然正确地将6/2除法计算为3!在这一步,您已经看到使用returnawaitpromise和returnpromise之间没有区别。至少在处理成功的Promise时是这样。但让我们进一步探索!2.Differentbehavior(不同的行为)现在让我们采用另一种方法,尤其是在尝试处理Promise.reject的实现时。为了让函数promiseDivision(n1,n2)返回拒绝的承诺,我们将第二个参数设置为0。由于promiseDivision(n1,0)现在将拒绝,让我们将执行放在try{...}catch(error){...}中——看看是否捕获了拒绝的承诺。好的,让我们使用带有await关键字的returnawaitpromiseDivision(5,0)表达式:asyncfunctiondivideWithAwait(){try{returnawaitpromisedDivision(5,0);}catch(error){//拒绝捕获console.log(error);//记录Error('Cannotdivideby0')}}asyncfunctionrun(){constresult=awaitdivideWithAwait();控制台日志(结果);//记录未定义}run();由于不可能被零除,promiseDivision(5,0)返回一个拒绝的承诺。catch(error){...}成功捕获了promiseDivision(5,0)抛出的被拒绝的promise。省略await的第二种方法怎么样?异步函数divideWithoutAwait(){try{returnpromisedDivision(5,0);}catch(error){//拒绝未被捕获console.log(error);}}asyncfunctionrun(){constresult=awaitdivideWithoutAwait();}跑步();//UncaughtError:Cannotdivideby0但是,这次catch(error){...}没有捕获到被拒绝的promise。现在你可以很容易地看出使用returnawaitpromise和returnpromise之间的主要区别:当被包装到try{...}中时,附近的catch(error){...}只有在等待promise时才会捕获被拒绝的promise(这对于returnawaitpromise是正确的)。当放入try{...}catch(error){...}时,只有promise被await(returnawaitpromise)修改,最新的catch(error){...}才会捕获到rejection的结果承诺!3.结论在大多数情况下,尤其是当Promise返回一个成功的结果(resolve)时,returnawaitpromise和returnpromise并没有太大区别。但是,如果你想从异步函数的返回结果1中捕获promise的拒绝结果,你应该显式地使用returnawaitpromise表达式,并有意地用await装饰它!try{...catch(error){...}语句只能在等待执行后捕获拒绝的promise结果!
