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

一个以回调函数为参数的函数转化为返回一个Promise的具体例子

时间:2023-04-05 16:06:37 HTML5

我开发了一个函数loadScript,可以动态加载指定的本地JavaScript文件。源码如下:functionloadScript(src,callback){letscript=document.createElement('script');脚本.src=src;script.onload=()=>回调(空,脚本);script.onerror=()=>callback(newError(`${src}`的脚本加载错误));document.head.append(script);}然后开发一个函数promisify,它可以将传入的任意函数f转化为一个返回参数为Promise类型的新函数。functionpromisify(f){returnfunction(...args){//返回一个包装函数(*)returnnewPromise((resolve,reject)=>{functioncallback(err,result){//我们的自定义回调forf(**)if(err){reject(err);}else{resolve(result);}}args.push(callback);//将自定义回调附加到f参数的末尾f.call(this,...args);//调用原函数});};}具体消费方法:letloadScriptPromise=promisify(loadScript);loadScriptPromise("1.js").then((script)=>{console.log('loaded:',script);hello();});其中,1.js的内容:functionhello(){console.log("hello!");}接下来我们进行单步调试。待修改的loadScript包含两个函数:调用promisify和返回一个新函数。这个新函数包含一个闭包f,它在没有promisify的情况下调用旧函数。使用这个新函数加载1.js:进入这个新函数并执行执行体:函数体内部可以随时访问回调:我们期望脚本onload事件发生时,会使用resolve和reject自带Promise传递参数,所以可以写一个回调函数,在这个回调函数中,使用Promise的resolve传递结果。并且希望将这个回调函数传递给原来的loadScript函数。我们通过函数原型链上的call函数来达到调用原始loadScript函数的目的。而此时的回调函数确实是我们写在promisify函数中使用Promiseresolve传递结果的函数。之后异步触发script.onload:通过resolve,将加载的script元素通过then传递给promise对象注册的回调函数。