成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Callback 與 Promise 間的橋梁 —— promisify

RayKr / 1638人閱讀

摘要:今天要介紹的是,就是回調(diào)函數(shù)與間的橋梁。什么樣的叫有兩個條件回調(diào)函數(shù)在主函數(shù)中的參數(shù)位置必須是最后一個回調(diào)函數(shù)參數(shù)中的第一個參數(shù)必須是。

作者:晃晃
本文原創(chuàng),轉(zhuǎn)載請注明作者及出處

Promise 自問世以來,得到了大量的應(yīng)用,簡直是 javascript 中的神器。它很好地解決了異步方法的回調(diào)地獄、提供了我們在異步方法中使用 return 的能力,并將 callback 的調(diào)用納入了自己的管理,而不是交給異步函數(shù)后我們就無能為力了(經(jīng)常有 callback 被莫名調(diào)用兩次而導(dǎo)致程序出錯)。

今天要介紹的是 Promisify,就是回調(diào)函數(shù)與 Promise 間的橋梁。

1. promisify 介紹

什么是 promisify 呢?顧名思義,就是“promise 化”,將一個不是promise的方法變成 promise 。舉個例子:

// 原有的callback調(diào)用
fs.readFile("test.js", function(err, data) {
    if (!err) {
        console.log(data);
    } else {
        console.log(err);
    }
});

// promisify后
var readFileAsync = promisify(fs.readFile);
readFileAsync("test.js").then(data => {
    console.log(data);
}, err => {
    console.log(err);
});

這兩個方法效果上是等價的,但是從掌控性來說的話,我更喜歡后面的寫法。

那么什么樣的方法可以通過 promisify 變成 promise 呢?這里就需要介紹一個名詞,nodeCallback。什么樣的 callback 叫 nodeCallback ?

nodeCallback 有兩個條件:1. 回調(diào)函數(shù)在主函數(shù)中的參數(shù)位置必須是最后一個;2. 回調(diào)函數(shù)參數(shù)中的第一個參數(shù)必須是 error 。舉個例子:

回調(diào)函數(shù)在主函數(shù)中的參數(shù)位置

// 正確
function main(a, b, c, callback) {
    
}

// 錯誤
function main(callback, a, b, c) {
    
}

回調(diào)函數(shù)參數(shù)中的第一個參數(shù)必須是 error

// 正確
function callback(error, result1, result2) {
    
}

// 錯誤
function callback(result1, result2, error) {
    
}

這樣,通過 nodeCallback ,我們定義了一個能被 promisify 的函數(shù)的格式,即,滿足 nodeCallback 形式的方法,我們可以通過 promisify 來讓它變成一個返回 promise 的方法。

2. promisify 的實現(xiàn)

下面我們來根據(jù)上述條件來手動實現(xiàn)一個 promisify 。

首先 promisify 需要返回一個 function ,并且這個 function 要返回一個 promise

var promisify = (func) => {
    return function() {
        var ctx = this;
        return new Promise(resolve => {
            return func.call(ctx, ...arguments);
        })
    }
}

其次,原 func 的最后一個參數(shù)是 callback

var promisify = (func) => {
    return function() {
        var ctx = this;
        return new Promise(resolve => {
            return func.call(ctx, ...arguments, function() {
                resolve(arguments);
            });
        })
    }
}

然后,回調(diào)函數(shù)中的第一個參數(shù)是 error 標記

var promisify = (func) => {
    return function() {
        var ctx = this;
        return new Promise((resolve, reject) => {
            return func.call(ctx, ...arguments, function() {
                var args = Array.prototype.map.call(arguments, item => item);
                var err = args.shift();
                if (err) {
                    reject(err);
                } else {
                    resolve(args);
                }
            });
        })
    }
}

最后,做一些優(yōu)化,比如 this 作用域的自定義、回參只有一個時不返回數(shù)組

var promisify = (func, ctx) => {
    // 返回一個新的function
    return function() {
        // 初始化this作用域
        var ctx = ctx || this;
        // 新方法返回的promise
        return new Promise((resolve, reject) => {
            // 調(diào)用原來的非promise方法func,綁定作用域,傳參,以及callback(callback為func的最后一個參數(shù))
            func.call(ctx, ...arguments, function() {
                // 將回調(diào)函數(shù)中的的第一個參數(shù)error多帶帶取出
                var args = Array.prototype.map.call(arguments, item => item);
                var err = args.shift();
                // 判斷是否有error
                if (err) {
                    reject(err)
                } else {
                    // 沒有error則將后續(xù)參數(shù)resolve出來
                    args = args.length > 1 ? args : args[0];
                    resolve(args);
                }
            });
        })
    };
};

測試

// nodeCallback方法func1
var func1 = function(a, b, c, callback) {
    callback(null, a+b+c);
}
// promise化后的func2
var func2 = promisify(func1);
// 調(diào)用后輸出6
func1(1, 2, 3, (err, reuslt) => {
    if (!err) {
        console.log(result); //輸出6
    }
})
func2(1, 2, 3).then(console.log); //輸出6

以上便是 promisify 的介紹和實現(xiàn),事實上有很多用 callback 來實現(xiàn)異步的第三方庫提供的方法都是按照 nodeCallback 格式的,所以它們都可以通過 promisify 來讓它變成 promise ,在遇到這些方法的時候就可以更靈活地使用啦。

iKcamp官網(wǎng):http://www.ikcamp.com

訪問官網(wǎng)更快閱讀全部免費分享課程:《iKcamp出品|全網(wǎng)最新|微信小程序|基于最新版1.0開發(fā)者工具之初中級培訓(xùn)教程分享》。
包含:文章、視頻、源代碼

iKcamp原創(chuàng)新書《移動Web前端高效開發(fā)實戰(zhàn)》已在亞馬遜、京東、當(dāng)當(dāng)開售。

【11月11號】上海iKcamp最新活動

報名地址:http://www.huodongxing.com/ev...

“天天練口語”小程序總榜排名第四、教育類排名第一的研發(fā)團隊,面對面溝通交流。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/89433.html

相關(guān)文章

  • util.promisify 的那些事兒

    摘要:自定義的化有那么一些場景,是不能夠直接使用來進行轉(zhuǎn)換的,有大概這么兩種情況沒有遵循約定的回調(diào)函數(shù)返回多個參數(shù)的回調(diào)函數(shù)首先是第一個,如果沒有遵循我們的約定,很可能導(dǎo)致的誤判,得不到正確的反饋。 util.promisify是在node.js 8.x版本中新增的一個工具,用于將老式的Error first callback轉(zhuǎn)換為Promise對象,讓老項目改造變得更為輕松。 在官方推...

    shuibo 評論0 收藏0
  • Promisify 的源碼解析

    摘要:參考文檔升級后的函數(shù)回調(diào)參數(shù)問題中的使用方法和還是不一樣的源碼講解的內(nèi)部機制優(yōu)化相關(guān)內(nèi)容文章官方文檔簡述使用過的都知道這個方法的作用,通過該方法會讓形式的函數(shù)風(fēng)格轉(zhuǎn)換成方法,可以認為是一顆語法糖,例如接下來我們就分析一下這個的內(nèi)部流程。 參考文檔 升級bluebird 3后Promise.promisify的函數(shù)回調(diào)參數(shù)問題:3中的使用方法和2還是不一樣的 How does Bl...

    gougoujiang 評論0 收藏0
  • Promise化,Promisify,將函數(shù)改成 既支持Callback回調(diào),又支持Promise

    摘要:初學(xué),用開發(fā)項目。而且還是個不小的項目,說起來挺冒險的。一開始比較簡單,并沒有使用也能順利進行,隨著開發(fā)的深入,到了不用不行的地步了。于是產(chǎn)生了一個問題,一些之前寫的方法并不支持,如果直接改成,那之前調(diào)用過的地方也都得改,工作量有點大。 初學(xué) Node.js,用 Express 開發(fā) Web 項目。而且還是個不小的項目,說起來挺冒險的。 一開始比較簡單,并沒有使用 Promise 也能...

    wushuiyong 評論0 收藏0
  • Promise遍歷(循環(huán),無窮多的then)遇到的問題及三個解決方案

    摘要:今天碰到一個需要用做無窮循環(huán)的一個案例,頓時腦洞大開。事情是這樣的,有這樣的一群異步函數(shù),將它們封裝成,依次放入一個數(shù)組內(nèi)需要讓數(shù)組里的每一個依次進行,最后一個執(zhí)行完就結(jié)束。 今天碰到一個需要用Promise做無窮循環(huán)then的一個案例,頓時腦洞大開。事情是這樣的,有這樣的一群異步函數(shù), var func1 = function(callback){ setTimeout(fu...

    freecode 評論0 收藏0
  • 適配器在JavaScript中的體現(xiàn)

    摘要:而適配器其實在中應(yīng)該是比較常見的一種了。在維基百科中,關(guān)于適配器模式的定義為在軟件工程中,適配器模式是一種軟件設(shè)計模式,允許從另一個接口使用現(xiàn)有類的接口。 適配器設(shè)計模式在JavaScript中非常有用,在處理跨瀏覽器兼容問題、整合多個第三方SDK的調(diào)用,都可以看到它的身影。 其實在日常開發(fā)中,很多時候會不經(jīng)意間寫出符合某種設(shè)計模式的代碼,畢竟設(shè)計模式就是老前輩們總結(jié)提煉出來的一些能...

    z2xy 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<