首页 > 编程语言 >JavaScript 异步函数的 Promisification 处理

JavaScript 异步函数的 Promisification 处理

时间:2022-08-15 10:38:50浏览次数:49  
标签:function src 异步 函数 err script JavaScript Promisification Promise

Promisification 是一个很长的词,表示一个编程范式的转变,即将接受回调的函数转换为一个返回类型为 Promise 的函数。

我们现实的开发项目中经常需要这种转换,因为许多函数和库都是基于回调的,但是 Promise 更方便,所以对它们进行 Promisification 处理是有意义的。

下面是一个简单的例子。

function loadScript(src, callback) {
  let script = document.createElement('script');
  script.src = src;

  script.onload = () => callback(null, script);
  script.onerror = () => callback(new Error(`Script load error for ${src}`));

  document.head.append(script);
}

这段代码,动态创建一个 script 元素,待其加载完毕后,会触发 onl oad 事件指定的回调函数。

运行时,loadScript 的调用者,负责指定回调函数:

loadScript('path/script.js', (err, script) => {...})

下面我们将会对这个函数进行 Promisification 改造。

我们将创建一个新函数 loadScriptPromise(src),它执行相同的操作(加载脚本),但返回一个 Promise 而不是使用回调。

换句话说,我们只传递 src (没有回调)并得到一个 Promise 作为返回参数,当加载成功时使用创建并加载好的 script 进行 resolve,否则通过 reject 抛出错误。

改造后的函数:

let loadScriptPromise = function(src) {
  return new Promise((resolve, reject) => {
    loadScript(src, (err, script) => {
      if (err) reject(err);
      else resolve(script);
    });
  });
};

消费代码:

loadScriptPromise('path/script.js').then(...)

正如我们所见,新函数是原始 loadScript 函数的包装器。

在实践中,我们可能需要 Promisify 多个函数,所以构造一个 helper 函数显得更有意义。

我们称这个函数为 promisify(f):它接受一个准备被改造成 Promise 的函数 f, 并返回一个 wrapper 函数。

完整实现如下:

function promisify(f) {
  return function (...args) { // return a wrapper-function (*)
    return new Promise((resolve, reject) => {
      function callback(err, result) { // our custom callback for f (**)
        if (err) {
          reject(err);
        } else {
          resolve(result);
        }
      }

      args.push(callback); // append our custom callback to the end of f arguments

      f.call(this, ...args); // call the original function
    });
  };
}

消费代码:

let loadScriptPromise = promisify(loadScript);
loadScriptPromise(...).then(...);

标签:function,src,异步,函数,err,script,JavaScript,Promisification,Promise
From: https://www.cnblogs.com/sap-jerry/p/16587342.html

相关文章

  • .NET异步编程模式(二)
    在C#1的时候就包含了APM,在APM模型中,异步操作通过IAsyncResult接口实现,包括两个方法BeginOperationName和EndOperationName,分别表示开始和结束异步操作。Demo我......
  • .NET异步编程模式(三)
    EAP(Event-basedAsynchronousPattern)是基于事件的异步模式,在.NETFramework2.0中引入。EAP需要一个有Async后缀方法和一个或多个事件。EAP不再推荐用于新开发。......
  • JavaScript快速入门-01-环境搭建
    1环境搭建  搭建JavaScript开发环境有很多种组合,本文中采用VisualStudioCode和Node.js的组合,详细如下所示:1.1Node.js环境搭建1.1.1下载Node.js  不管是基......
  • JavaScript关于cookie
        1.http和httpshttp,https都是网络传输协议是用于网络相关传输,http走的是明文传输,https走的密文传输(内部采用对称加密以及非对称加密)。对应的https安全性......
  • 小程序uni-app发起网络异步请求
    //uni.request({ // url:'api/boxs/search', // //使用监听函数防止this指向改变 // success:res=>{ // //判断是否成功返回数据 // if(res......
  • 【爬虫实例3】异步爬取大量数据
    1、导入模块importrequestsimportcsvfromconcurrent.futuresimportThreadPoolExecutor2、先获取第一个页面的内容分析得到该页面的数据是从getPriceData.html页......
  • 【Javascript小知识点】将对象中内容打印到控制台
    将对象中内容打印到控制台    有时结果打印到控制台却显示为[objectObject]。我们想查看其中的内容时,怎么也看不到,这样会把我们急死,非常的危险。于是,我们可以使用J......
  • JavaScript 对 DOM 元素排序
    <!DOCTYPEhtml><html><head><styletype="text/css">#wrapdiv{float:left;}#wrap:after{......
  • 事件一些补充 以及同步异步概念
    事件补充事件onload事件:当网页中的所有资源都加在完成之后执行这个事件通常是将script标签放到head标签中的时候使用。因为放在head中默认是获取不到body中的内容的,但是......
  • JavaScript ES6新增
    命名修饰符let:不能重复声明变量、块级作用域leta=1;leta=2;//报错const:初始化常量,必须给初始值,否则报错、在同一个作用域内,const定义的常量不能修改其值......