それらに関する wiki 記事があります: ( http://en.wikipedia.org/wiki/Futures_and_promises、http://en.wikipedia.org/wiki/Thunk_(delayed_computation) )。しかし、プログラミング言語の概念としての3つの正確な違いは何ですか? future と promise は並行プログラミングでのみ適用できますか?
4 に答える
誰もが読めるので、javascript を使用してそれぞれの例を示します。
このコードを本番環境で使用しないでください。実際のライブラリを使用してください。優れたライブラリがたくさんあります。
var a, b, c, async_obj; // assume exist
// CommonJS - for reference purposes
try {
async_obj.asyncMethod(a, b, c, function (error1, result1) {
if (error1) {
console.error(error1);
} else {
console.log(result1);
}
});
} catch (ex1) {
console.error(ex1);
}
// Thunk - "a parameterless closure created to prevent the evaluation of an expression until forced at a later time"
function makeThunkForAsyncMethod (cb) {
return function () {
async_obj.asyncMethod(a, b, c, cb);
}
}
var my_thunk = makeThunkForAsyncMethod(function (error1, result1) {
if (error1) {
console.error(error1);
} else {
console.log(result1);
}
});
setTimeout(function () {
try {
my_thunk();
} catch (ex1) {
console.error(ex1);
}
}, 5e3);
// Promise - "a writable, single assignment container which sets the value of the future"
function makePromiseForAsyncMethod () {
var
future_then_cb,
future_catch_cb,
future
;
future = {
then: function (cb) {
future_then_cb = cb;
},
catch: function (cb) {
future_catch_cb = cb;
};
};
try {
async_obj.asyncMethod(a, b, c, function (error1, result1) {
if (error1) {
if (future_catch_cb) {
future_catch_cb(error1)
}
} else {
if (future_then_cb) {
future_then_cb(result1);
}
}
});
} catch (ex1) {
setTimeout(function () {
if (future_catch_cb) {
future_catch_cb(ex1);
}
});
}
return future;
}
// Future - "a read-only placeholder view of a variable"
var my_future = makePromiseForAsyncMethod();
my_future
.then(function (result) {
console.log(result);
})
.catch(function (error) {
console.error(error);
})
;
Promise チェーンは上記の不自然な例のようになりますが、コレクションで機能し、より堅牢になります。
thunk
関数型プログラミングでは、との最も大きな違いは純粋promise
ですが、thunk
は純粋でpromise
はありません。
function thunkDemo() {
return function(callback) {
asyncMethod(someParameter, callback);
};
}
function promiseDemo() {
return new Promise(function(resolve, reject) {
asyncMethod(someParameter, function(err, data) {
if(err) return reject(err);
resolve(data);
});
});
}
がthunkDemo
呼び出されると、内部メソッドが呼び出されるまで asyncMethod は呼び出されないため、thunkDemo は純粋であり、副作用はありません。
がpromiseDemo
呼び出されると、すぐに asyncMethod が呼び出されます。つまり、純粋ではありません。
サンクは、呼び出しを適応させるか、何らかの方法で準備/変更してから適切な関数にリダイレクトするためにのみ使用される小さな関数の一般的な概念です。プロミス、フューチャー、クロージャー、ラッパー、スタブ、または一部の OO 言語 (C++ など) における仮想関数テーブルの概念の実装などは、サンクの特別な使用例にすぎません (サンクはそれらを実装するためによく使用されます)。
これらは非常に広い用語であり、その使用法と解釈は文脈によって異なります。したがって、特定のコンテキストに対してのみ特定の答えを与えることができます。
たとえば、javascript promise ライブラリでは、リンクされた wiki 記事がそれぞれ「promise」と「future」と呼んでいるものに対して、「deferred」と「promise」という用語が使用されます。値、および「約束」はそれを読み取るためのインターフェースであり、依存する値の新しい約束を簡単に構築できるようにする詳細がいくつかありますが、元の約束を実際に変更することはありません。
JS ライブラリ "co" ( https://github.com/visionmedia/co ) に出くわしました。「サンク」について聞いたのは初めてで、slfの回答とは少し異なる意味でこの用語を使用しているようで、リンクされたwikiよりもはるかに具体的です。値を返すのはパラメータのない関数ではなく、多くの場合非同期で、値を指定してコールバックを呼び出すコールバックを受け入れる関数です。
この特定のライブラリの場合、サンクとプロミスは互いに非常に近いものです。プロミスは、値を取得するためのコールバックを設定する「then」メソッド関数を持つオブジェクトです。サンクは直接、値を取得するためのコールバックを設定する関数です。