thunk,期货和承诺有什么区别?

时间:2013-09-10 03:14:53

标签: promise future delayed-execution thunk

有关于它们的维基文章:(http://en.wikipedia.org/wiki/Futures_and_promiseshttp://en.wikipedia.org/wiki/Thunk_(delayed_computation))。但我不确定三者作为编程语言概念之间的确切差异是什么?期货和承诺只适用于并发编程吗?

4 个答案:

答案 0 :(得分:16)

每个人的一个例子,使用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链就像上面提到的例子一样,但它可以用于集合并且更加健壮。

答案 1 :(得分:13)

在函数式编程中,thunkpromise之间的差异最大,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,这意味着它不是纯粹的。

答案 2 :(得分:3)

Thunk是一个小函数的一般概念,它仅用于调整调用或以某种方式准备/修改它,然后重定向到正确的函数。诸如承诺,期货,闭包,包装,存根或某些OO语言(如C ++)中虚函数表概念的实现之类的东西只是thunk的特殊用例(thunks通常用于实现它们)。

答案 3 :(得分:2)

这些术语相当广泛,其用法和解释因环境而异。因此,只能针对特定背景给出具体答案。

例如,在javascript promise库中,术语“deferred”和“promise”分别用于链接的wiki文章分别称为“promise”和“future”,因为“deferred”是解析的接口或拒绝该值,“promise”是用于读取它的接口,其中一些更具体的内容允许轻松构建依赖值的新承诺,但实际上并未改变原始承诺。

我偶然发现了JS库“co”(https://github.com/visionmedia/co)。 这是我第一次听到“thunks”,它似乎使用的术语与slf的答案略有不同,并且比你的链接wiki更具体。它不是一个返回值的无参数函数,它是一个接受回调函数的函数,它将使用值调用回调函数,通常是异步的。

在这个特定的库中,thunks和promises彼此非常接近:promise是一个带有“then”方法函数的对象,它设置一个回调来获取值; thunk直接是一个设置回调以获取值的函数。