promise - ¿Cuál es la diferencia entre thunk, futuros y promesas?
future delayed-execution (4)
Hay artículos de la wiki sobre ellos: ( http://en.wikipedia.org/wiki/Futures_and_promises , http://en.wikipedia.org/wiki/Thunk_(delayed_computation) ). Pero no estoy seguro de cuáles son las diferencias exactas entre los tres como concepto de lenguaje de programación. ¿Los futuros y las promesas solo son aplicables en la programación concurrente?
En la programación funcional, la mayor diferencia entre thunk
y promise
es que thunk
es puro, mientras que la promise
es impura.
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);
});
});
}
cuando se llama a thunkDemo, no se llamará al método asyncMethod hasta que se llame al método interno, por lo que thunkDemo es puro sin efectos secundarios.
cuando se llama a promiseDemo
, llamará a asyncMethod inmediatamente, lo que significa que no es puro.
Estos son términos bastante amplios, y su uso e interpretación varían según el contexto. Por lo tanto, solo se puede dar una respuesta específica para un contexto específico.
En las bibliotecas de promesa de javascript, por ejemplo, los términos "diferido" y "promesa" se usan para lo que su artículo de wiki vinculado denomina "promesa" y "futuro" respectivamente, en el sentido de que "diferido" es la interfaz para resolver o rechazar la valor, y "promesa" es la interfaz para leerlo, con algunos detalles más que permiten construir fácilmente nuevas promesas para valores dependientes, pero en realidad no cambian la promesa original.
Me topé con la biblioteca "co" de JS ( https://github.com/visionmedia/co ). Fue la primera vez que escuché sobre "thunks", y parece estar usando el término en un sentido ligeramente diferente al de la respuesta de slf, y mucho más específico que tu wiki vinculado también. No es una función sin parámetros que devuelve el valor, es una función que acepta una devolución de llamada que llamará a la devolución de llamada con el valor, a menudo de forma asíncrona.
En el caso de esta biblioteca específica, los thunks y las promesas están muy cerca uno del otro: una promesa es un objeto con una función de método "entonces" que establece una devolución de llamada para obtener el valor; un procesador es directamente una función que establece una devolución de llamada para obtener el valor.
Thunk es un concepto general de una función pequeña que se usa solo para adaptar la llamada o para prepararla / modificarla de alguna manera y luego redirigirla a la función apropiada. Cosas como promesas, futuros, cierres, envoltorios, talones o implementaciones del concepto de tablas de funciones virtuales en algunos lenguajes OO (como C ++) son solo casos de uso especiales de thunks (los thunks se usan a menudo para implementarlos).
Un ejemplo de cada uno, usando javascript ya que todos pueden leerlo.
Por favor, no use este código en producción, use una biblioteca real, hay muchos buenos.
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);
})
;
Una cadena de promesa sería como el ejemplo creado anteriormente, pero funcionaría en colecciones y sería más robusta.