1. 程式人生 > 其它 >(Javascript)Promisificcatiion

(Javascript)Promisificcatiion

技術標籤:Javascript 相關知識點javascriptjs

  • “Promisification” 指將一個接受回撥的函式轉換為一個返回 promise 的函式。
  • 因為使用promise更加方便,所以將基於回撥的函式和庫 promisify 是有意義的
//callback回撥函式需要傳入失敗資訊和成功資訊
//由callback函式來對成功資訊和失敗資訊進行處理
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); } // 用法: // loadScript('path/script.js', (err, script) => {...})

  • 將 loadScript promisify
  1. 第一種方法
let loadScriptPromise = function(src) {
  return new
Promise((resolve, reject) => { //將成功資訊和失敗資訊用resolve和reject包裝之後 //作為Promise物件返回 loadScript(src, (err, script) => { if (err) reject(err); else resolve(script); }); }); }; // 用法: // loadScriptPromise('path/script.js').then(...)
  1. 第二種方法
function promisify(f) {
  return function
(...args) { // 返回一個包裝函式,...args在這裡是要載入的資料(例如'path/script.js') return new Promise((resolve, reject) => { function callback(err, result) { // 我們對 f 的自定義的回撥 (**) if (err) { reject(err); } else { resolve(result); } } //loadScript(src, callback) args.push(callback); // 將我們的自定義的回撥附加到 f 引數(arguments)的末尾 f.call(this, ...args); // 呼叫原始的函式 }); }; } // 用法: let loadScriptPromise = promisify(loadScript); loadScriptPromise(...).then(...);
  • 如果原始的 f 期望一個帶有更多引數的回撥 callback(err, res1, res2, …)
// promisify(f, true) 來獲取結果陣列
function promisify(f, manyArgs = false) {
  return function (...args) {
    return new Promise((resolve, reject) => {
      function callback(err, ...results) { // 我們自定義的 f 的回撥
        if (err) {
          reject(err);
        } else {
          // 如果 manyArgs 被指定,則使用所有回撥的結果 resolve
          resolve(manyArgs ? results : results[0]);
        }
      }

      args.push(callback);

      f.call(this, ...args);
    });
  };
}

// 用法:
f = promisify(f, true);
f(...).then(arrayOfResults => ..., err => ...);