defer().promise 和 Promise 的区别

Difference between defer().promise and Promise

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

提前致谢

PS:我目前正在做一个 Promise 库,欢迎问题和 PRS:https://github.com/jiananshi/Promise-polyfill

嗯,这是关于 promise 解析源的。 Q 和许多其他图书馆提供两个 APIs:

  • 遗留 defer API - 在其中创建一个可以 .resolve(value) 的延迟,并且它承诺您可以 return.
  • 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 构造函数是安全的。

投掷安全

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

If either onFulfilled or onRejected throws an exception e, promise2 must be rejected with e as the reason

假设您从 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);
});

防止整个 class 程序员错误的发生。