(Javascript)Promisificcatiion
阿新 • • 發佈:2020-12-15
技術標籤: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
- 第一種方法
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(...)
- 第二種方法
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 => ...);