当前位置: 首页 > Web前端 > HTML5

JavaScript异步函数的Promisification处理

时间:2023-04-05 17:51:32 HTML5

Promisification是一个很长的词,表示编程范式转换,即将接受回调的函数转换为返回Promise的函数。我们在实际开发项目中经常需要这样的改造,因为很多函数和库都是基于回调的,但是Promise更方便,所以对它们进行Promisify是有意义的。下面是一个简单的例子。functionloadScript(src,callback){letscript=document.createElement('script');脚本.src=src;script.onload=()=>回调(空,脚本);script.onerror=()=>callback(newError(`${src}`的脚本加载错误));document.head.append(script);}这段代码动态创建了一个script元素,加载后会触发onload事件指定的回调函数。在运行时,loadScript的调用者负责指定回调函数:loadScript('path/script.js',(err,script)=>{...})接下来,我们将对该函数进行Promisification转换。我们将创建一个新函数loadScriptPromise(src)来做同样的事情(加载脚本),但返回一个Promise而不是使用回调。也就是说,我们只传递src(没有回调),得到一个Promise作为返回参数,当加载成功时,使用创建和加载的脚本来解析,否则通过reject抛出错误。转换函数:letloadScriptPromise=function(src){returnnewPromise((resolve,reject)=>{loadScript(src,(err,script)=>{if(err)reject(err);elseresolve(script);});});};使用代码:loadScriptPromise('path/script.js').then(...)如我们所见,新函数是对原始loadScript函数的包装。在实践中,我们可能需要Promisify多个函数,因此构造一个辅助函数更有意义。我们称此函数为promisify(f):它接受一个准备好转换为Promise的函数f,并返回一个包装函数。完整的实现如下:functionpromisify(f){returnfunction(...args){//返回一个包装函数(*)returnnewPromise((resolve,reject)=>{functioncallback(err,result){//我们对f(**)的自定义回调if(err){reject(err);}else{resolve(result);}}args.push(callback);//将我们的自定义回调附加到fargumentsf.call(this,...args);//调用原函数});};}消费代码:letloadScriptPromise=promisify(loadScript);loadScriptPromise(...).then(...);