deferre().promise和promise之间的区别

Difference between defer().promise and Promise

本文关键字:promise 区别 之间 deferre      更新时间:2024-04-06

我知道defer将promise状态控制和进程分开。以Q为例,Q.defer().promiseQ.Promise返回的promise完全不同。为什么要这样设计?这两个承诺有什么区别?

好吧,这是关于promise解析源的。Q和其他一些库提供了两个API:

  • 传统defer API-在其中创建一个可以.resolve(value)的延迟,并且它有一个可以返回的承诺
  • promise构造函数-这是现代API,您可以在其中从完成源创建promise

大致操作:

var d = Q.defer();
setTimeout(function(){ d.resolve(); }, 1000); 
return d.promise;

与相同

return new Promise(function(resolve, reject){
   setTimeout(resolve, 1000);
});

所以你可能会问

为什么我们需要两个API

好吧,推迟API是第一位的。这是其他一些语言处理它的方式,这是论文处理它的方法,这是人们首先使用它的方式——然而,这两种API之间有一个重要的区别。promise构造函数是抛出安全的。

投掷安全

承诺抽象异常处理,并且是抛出安全的。如果你抛出一个承诺链,它会将该异常转换为拒绝,并引用规范:

如果onFulfilled或onRejected抛出异常e,则promise2必须被拒绝,并将e作为的原因

假设您正在从XHR请求解析JSON:

function get(){
    var d = Q.defer();
    if(cached) { // use cached version user edited in localStorage
        d.resolve(JSON.parse(cached));
    } else { // get from server
       myCallbackApi('/foo', function(res){ d.resolve(res); });
    }
}

现在,让我们看看promise构造函数版本:

function get(){
    return new Promise(function(resolve, reject){ 
        if(cached) { // use cached version user edited in localStorage
            resolve(JSON.parse(cached));
        } else { // get from server
           myCallbackApi('/foo', resolve);
        }
    });
}

现在,假设您的服务器以某种方式向您发送了无效的JSON(或者用户将其编辑为无效状态),然后您缓存了它

在延迟版本中,它同步抛出。所以你一般都要防范它。在底层版本中则不然。顶级版本的使用情况如下:

try{
  return get().catch(function(e){
     return handleException(e); // can also just pass as function
  });
} catch(e){ 
   handleException(e);
}

在底层版本中,promise构造函数将把throws转换为rejections,这样做就足够了:

return get().then(function(e){
   return handleException(e);
});

防止一整类程序员错误的发生。