CallbackとPromiseの橋梁——promisify
3816 ワード
CallbackとPromiseの橋梁-----promisify
Promiseは世に出て以来、多くの応用を得て、まさにjavascriptの神器です.これは非常によく非同期の方法を解決しました.私たちは非同期の方法でreturnを使用する能力を提供しています.そしてcalbackの呼び出しを自分の管理に組み入れました.非同期の関数に任せてからはどうすることもできません.
1.promisify紹介
promisifyとは何ですか?その名の通り「プロミス化」して、プロミスではない方法をプロミスに変えます.例を挙げます
では、どのような方法でプロモーションを通じてプロモーションに変えることができますか?ここでは名詞を紹介します.nodeCallback.どのようなcalbackがnodeCallbackですか?
nodeCallbackには2つの条件があります.1.コールバック関数の主関数におけるパラメータ位置は最後でなければなりません.2.コールバック関数パラメータの中の最初のパラメータはerrorでなければなりません.例を挙げます
2.promisifyの実現
以下、上記の条件に基づいて、手動でpromisifyを実現します.
まずpromisifyは一つのfunctionに戻ります.そしてこのfunctionは一つのpromiseに戻ります.
Promiseは世に出て以来、多くの応用を得て、まさにjavascriptの神器です.これは非常によく非同期の方法を解決しました.私たちは非同期の方法でreturnを使用する能力を提供しています.そしてcalbackの呼び出しを自分の管理に組み入れました.非同期の関数に任せてからはどうすることもできません.
1.promisify紹介
promisifyとは何ですか?その名の通り「プロミス化」して、プロミスではない方法をプロミスに変えます.例を挙げます
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);
});
この二つの方法は効果的には同等ですが、コントロール的には後ろの書き方が好きです.では、どのような方法でプロモーションを通じてプロモーションに変えることができますか?ここでは名詞を紹介します.nodeCallback.どのようなcalbackがnodeCallbackですか?
nodeCallbackには2つの条件があります.1.コールバック関数の主関数におけるパラメータ位置は最後でなければなりません.2.コールバック関数パラメータの中の最初のパラメータはerrorでなければなりません.例を挙げます
1.
//
function main(a, b, c, callback) {
}
//
function main(callback, a, b, c) {
}
2. error
//
function callback(error, result1, result2) {
}
//
function callback(result1, result2, error) {
}
このように、nodeCallbackを通じて、promisifyの関数のフォーマット、すなわち、nodeCallback形式を満たす方法を定義し、promisifyを通じてpromisifyに変えてpromiseに戻す方法があります.2.promisifyの実現
以下、上記の条件に基づいて、手動でpromisifyを実現します.
まずpromisifyは一つのfunctionに戻ります.そしてこのfunctionは一つのpromiseに戻ります.
var promisify = (func) => {
return function() {
var ctx = this;
return new Promise(resolve => {
return func.call(ctx, ...arguments);
})
}
}
次に、元funcの最後のパラメータはcalbackです.var promisify = (func) => {
return function() {
var ctx = this;
return new Promise(resolve => {
return func.call(ctx, ...arguments, function() {
resolve(arguments);
});
})
}
}
そして、コールバック関数の最初のパラメータは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);
}
});
})
}
}
最後に、いくつかの最適化を行います.例えば、thisスコープのカスタム、戻りは1つしかない場合、配列に戻りません.var promisify = (func, ctx) => {
// function
return function() {
// this
var ctx = ctx || this;
// promise
return new Promise((resolve, reject) => {
// promise func, , , callback(callback func )
func.call(ctx, ...arguments, function() {
// error
var args = Array.prototype.map.call(arguments, item => item);
var err = args.shift();
// error
if (err) {
reject(err)
} else {
// error 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);
// 6
func1(1, 2, 3, (err, reuslt) => {
if (!err) {
console.log(result); // 6
}
})
func2(1, 2, 3).then(console.log); // 6
以上がpromisifyの紹介と実現です.実際にはcalbackで非同期を実現する第三者ライブラリが提供する方法は全部nodeCallback形式ですので、promisifyでpromiseにすることができます.これらの方法に出会う時にもっと柔軟に使えます.