浅谈ECMAScript 6下的promises API

浅谈ECMAScript 6下的promises API9 2 构造函数 nbsp nbsp nbsp nbsp nbsp nbsp promise 的构造函数为以下形式 nbsp nbsp nbsp var nbsp p nbsp nbsp new nbsp Promise executor resolve nbsp reject nbsp nbsp nbsp 上面创建了一个行为由回调函数 exector 决定的 promise 使用参数来处理解决或者拒绝 p nbsp nbsp nbsp nbsp nbsp nbsp nbsp resolve x

    9.2. 构造函数

    
    promise 的构造函数为以下形式:
    

  1. var p = new Promise(executor(resolve, reject));


    上面创建了一个行为由回调函数 exector 决定的 promise。使用参数来处理解决或者拒绝 p:
        resolve(x),以 x 来解决 p:
            如果 x 是 then式的,那么它的结果会转到 p(包括通过 then() 注册的触发反馈)。
            否者,p 就以 x 处理 fulfilled 状态。
        reject(x),以 e 值来拒绝 p(通常为一个 Error 的子类)。


    9.3. 静态方法



    所有的 Promise 的静态方法都支持实例化:通过接收器来创建一个实例(像:new this),并且通过它来访问这些静态方法(this.resolve 与 Promise.resolve)。


    创建 promises:
        下面两种方式来创建接收器的实例。
        1. Promise.resolve(x):
        如果 x 是 then式的,它将转化为一个 promise(接收器的实例)。
        如果 x 是一个 promise,返回将没有变化。
        否者将会返回一个接收器的实例并且以 x 来处理 fulfilled 状态。


        2. Promise.reject(reason):创建一个新的promise,并且以 reason 值来处理拒绝状态。


    组合 promises:
        直观来说,静态方法 Promise.all() 和 Promise.race() 组合迭代的 promises 变为一个单一的 promise。即:
            1. 它们采用迭代。迭代的元素通过 this.resolve() 来转化为 promises。
            2. 它们返回一个新的 promise。这个 promise 返回一个新的接收器的实例。


    方式有:
        1. Promise.all(iterable):如此返回一个 promise
            如果迭代的元素均为 fulfilled 那么将其设置为 fulfilled。成功值:各个成功值生成的数组。            
            当元素中有任何一个失败时便设置其为 rejected。拒绝值:第一个解决状态的值。


        2. Promise.race(iterable):迭代的第一个被设置完毕的元素被用来解决返回的 promise。


    9.4. 继承原型



    Promise.prototype.then(onFulfilled, onRejected);

        1. 回调函数 onFulfilled 和 onRejected 被车称为 reactions。

        2. 如果该 promise 已经被设为 fulfilled,或者一旦变成 fulfilled 状态,那么回调函数 onFulfilled 就会被立即执行。相同,被触发之后 onRejected 也一样。
        3. then() 返回一个新的 promise Q(通过接收器的构造函数创建):
        任意 reactions 返回一个结果,Q 便使用其来通过。
        任意 reactions 抛出一个错误,Q 便使用其来拒绝。
        4. 触发 reactions:
        如果 onFulfilled 被触发了,那么一个通过状态的接收器就会被转发到 then() 的结果中。
        如果 onRejected 被触发了,那么一个拒绝状态的接收器就会被转发到 then() 的结果中。


    触发 reactions 的默认值可以以以下方式执行:

  1. function defaultOnFulfilled(x){


  2.     return x;

  3. }

  4. function defaultOnRejected(e){


  5.     throw e;

  6. }




    Promise.prototype.catch(onRejected):
        与 then(null, onRejected) 一样。






 10. promises 的优势与劣势



    10.1. 优势



    统一的异步 APIs
        promises 的一个重要的优点就是被越来越多的浏览器的异步 API 使用,统一了当前多样化和不兼容的各种模式和约定。看一下即将出现的两种基于 promise 的API。
        基于 promise 的 ferch API 替代 XMLHttpRequest:

  1. fetch(url)

  2. .then(request => request.text())

  3. .then(str => ...)




        fetch() 会对实际的请求返回一个 promise,text() 会对内容作为字符串返回一个 promise。
        ECMAScript 6 API 编程式导入模块也是基于 promise:

  1. System.import(‘some_modle.js’)

  2. .then(some_module => {


  3.     ...

  4. })




    promises VS events
        对比 events,promises 更适合做一次性结果的监听。不管你是在得到结果之前或者之后注册都不会影响你监听到结果。这是 promises 更本上的优势。另一方面,你不能使用它来处理一些反复性的事件。链式是         promise 的另一个优势,但是每次只能添加一个。
    
    promises VS callbacks
        对比回调函数,promises 具有更简洁的函数(方法)参数。在 callbacks 中,参数包含输入输出:

  1. fs.readFile(name, opts?, function(err, data))




        而 promise 中,所有的参数均只是输入:

  1. readFilePromisified(name, opts?)

  2. .then(dataHandler, errorHandler)


        
        此外,promises 的优势还包括更好的错误处理机制(异常的集成)和组合更任意更容易(因为你可以使用一些同步的工具,比如 Array.prototype.map())。


    10.2. 劣势



    Promises 对于单一的异步结果能处理的很好。但是它不擅长于:
        1. 反复性事件如果你对此感兴趣,可以看一下 reactive programming http://reactive-extensions.github.io/RxJS/
,关于链式处理普通的事件监听的巧妙方式。
        2. 数据流支持的标准正在完善中。


    ECMAScript 6 的 promises 缺少一下的两个基本功能点:
        1. 你无法取消。
        2. 你无法确定他们要在多久之后发生(例如在客户端用户界面展现进度条)。


    Q promises 库支持后者,并且也将计划添加到 Promises/A+。




 11. promises 与 生成器



    由于一个实用功能 Q.spawn(),你可以通过生成器来实现在浅协程里使用基于 promises 的函数。这是一份重要的优点使得代码看起来类似于同步,并且可以使用一些同步机制,比如说 try-catch:

  1. Q.spawn(function* () {


  2.     try {


  3.         let [foo, bar] = yield Promise.all([ // (A)

  4.             httpGet(‘foo.json’),

  5.             httpGet(‘bar.json’)

  6.         ]);

  7.         render(foo);

  8.         render(bar);

  9.     } catch (e){


  10.         console.log(‘Read failed: ‘+ e );

  11.     }

  12. });




    Q.spawn() 的参数是生成器函数。如果 yield 标识符是有效的,那么将发生下面的事情:
        1. 函数执行将被暂停。
        2. 操作符 yield 被函数返回(返回,描述的不确切,暂时忽略)。
        3. 随后函数会被恢复成一个值或者异常。前者情况继续执行之前暂停的那个点,yield 返回一个值。后者情况表达式被抛入函数中,类似 yield 操作符从内部被扔入。


    从而,很清楚的明白 Q.spawn() 所做的事情:当生成器函数产生一个 promise,spawn 便注册 reaction,等待处理。如果 promise 通过状态,生成器便会恢复一个结果。如果 promise 为拒绝,一个异常便会抛入注册器中。


    这是一个通过新的语法结构-异步函数。来添加支持 JS spawn 的提案 https://github.com/lukehoban/ecmascript-asyncawait
。之前例子作为异步函数应该如下。底层,并没有较多不同 – 异步函数基于生成器。

  1. asyc function(){


  2.     try {


  3.         let [foo, bar] = await Promise.all([

  4.             httpGet(‘foo.json’),

  5.             httpGet(‘bar.json’)

  6.         ]);

  7.         render(foo);

  8.         render(bar);

  9.     } catch (e){


  10.         console.log(‘Read failed: ‘+ e );

  11.     }

  12. }








 12. 调试 promises



    主要的挑战是调试异步代码中包含异步函数和方法的调用。异步调用源自于一个任务执行了一个新的任务。如果该新任务中有异常,堆栈跟踪只会覆盖该任务,不会包含之前任务的信息。所以在异步编程中你只能获得很少的调试信息。
    Google 的 chrome 最近开始可以调试异步代码。并不完全支持 promises,但是处理一般的异步编程做得非常不错。比如下面的实例,first 异步调用 返回调用 third 的 second。

  1. function first(){


  2.     setTimeout(function () {
     second(‘a’) }, 0); //(A)

  3. }

  4. function second(){


  5.     setTimeout(function () {
     third(‘b’) }, 0); //(B)

  6. } 

  7. function third(){


  8.     debugger;

  9. }

  10. first();



    正如截图中所示,调试器展现一个包含三个函数的跟踪堆栈。它包含了 line A 和 line B 处的异步函数。


    浅谈ECMAScript 6下的promises API



 13. promises 内部窥秘



    本段,我们将从不同的角度来看一下 promises:不再学习如何使用 promise API,我们将了解一下它的简单实现。这个视角将帮助我们实现一个 promises。


    promises 的实现被称为 DemoPromise 和 在 GitHub 上可用的实例 https://github.com/rauschma/demo_promise
)。为了更容易理解,将不会完全匹配 API。但是它将足够使你了解在实现 promises 过程会中面对的各种难题。


    DemoPromises 是一个含有三个原型方法的构造函数:
        1. DemoPromises.prototype.resolve(value)
        2. DemoPromises.prototype.reject(reason)
        3. DemoPromises.prototype.then(onFulfilled, onRejected)
    
    在此,resolve 和 reject 为方法(而不是传递给传递给构造函数作为参数的回调函数)。
    

    13.1 一个独立的 promise



    首先我们需要实现一个最少功能的独立的 promise :
        1. 你可以创建一个 promise。
        2. 你可以通过或者拒绝一个 promise 并且只能处理它一次。
        3. 你可以通过 then() 来注册 reactions(回调函数)。该方法不支持链式(该处应该是支持链式),就是说,其不返回任何东西。它需要被立即执行不管该 promise 是否已经被处理。


    以下是使用第一步所实现的:

  1. var dp = new DemoPromise();

  2. dp.resolve(‘abc’);

  3. dp.then(function(value){


  4.     console.log(value); // abc

  5. });




    下面图标说明了我们第一个 DemoPromise 是如何实现的:


浅谈ECMAScript 6下的promises API

    让我们首先研究下 then()。它必须处理两个情况:
        1. 如果 promise 还在执行中,那么将在 promise 被处理完毕之后调用 onFulfilled 或者 onRejected 的时候使用。
        2. 如果 promise 已经被通过或者拒绝,onFulfilled 或者 onRejected 将被立即调用。

  1. DemoPromise.prototype.then = function (onFulfilled, onRejected) {


  2.     var self = this;

  3.     var fulfilledTask = function () {


  4.         onFulfilled(self.promiseResult);

  5.     };

  6.     var rejectedTask = function () {


  7.         onRejected(self.promiseResult);

  8.     };

  9.     switch (this.promiseState) {


  10.         case ‘pending’:

  11.             this.fulfillReactions.push(fulfilledTask);

  12.             this.rejectReactions.push(rejectedTask);

  13.             break;

  14.         case ‘fulfilled’:

  15.             addToTaskQueue(fulfilledTask);

  16.             break;

  17.         case ‘rejected’:

  18.             addToTaskQueue(rejectedTask);

  19.             break;

  20.     }

  21. };

  22. function addToTaskQueue(task) {


  23.     setTimeout(task, 0);

  24. }






    resolve() 工作原理如下:如果 promise 已经被处理完毕,
将不做任何事情(确保一个 promise 只被处理一次)。否则,promise 的状态转变为 fulfilled 并且结果缓存到 this.promiseResult。所有入队到通过状态 reactions 的将被立即执行。

  1. Promise.prototype.resolve = function (value) {


  2.     // 为执行回调函数方法 如果不为状态 pending 为在 then 时刻已经处理执行过,立即跳出

  3.     if (this.promiseState !== ‘pending’) return;

  4.     this.promiseState = ‘fulfilled’;

  5.     this.promiseResult = value;

  6.     this._clearAndEnqueueReactions(this.fulfillReactions);

  7.     return this; // 链式

  8. };

  9. Promise.prototype._clearAndEnqueueReactions = function (reactions) {


  10.     this.fulfillReactions = undefined;

  11.     this.rejectReactions = undefined;

  12.     reactions.map(addToTaskQueue);

  13. };




    reject() 与 resolve() 类似。


    13.2 链式(注意,这部分已经为下一步扁平化做好了基础)

    接下来,我们将实现链式:
        1. then() 返回的 promise 实际上是 onFulfilled 或者 onRejected 被执行后所返回的。
        2. 如果 onFulfilled 或者 onRejectecd 缺失,那么
成都
网站建设
不管它们所传递的是什么, promise 通过 then() 返回出来。


        浅谈ECMAScript 6下的promises API

    显然,只需要调整下 then():

  1. DemoPromise.prototype.then = function (onFulfilled, onRejected) {


  2.     var returnValue = new DemoPromise(); // (A)

  3.     var self = this;



  4.     var fulfilledTask;

  5.     if (typeof onFulfilled === ‘function’) {


  6.         fulfilledTask = function () {


  7.             var r = onFulfilled(self.promiseResult);

  8.             returnValue.resolve(r); // (B)

  9.         };

  10.     } else {


  11.         fulfilledTask = function () {


  12.             returnValue.resolve(self.promiseResult); // (C)

  13.         };

  14.     }



  15.     var rejectedTask;

  16.     if (typeof onRejected === ‘function’) {


  17.         rejectedTask = function () {


  18.             var r = onRejected(self.promiseResult);

  19.             returnValue.resolve(r); // (D)

  20.         };

  21.     } else {


  22.         rejectedTask = function () {


  23.             // Important: we must reject here!

  24.             // Normally, result of `onRejected` is used to resolve

  25.             returnValue.reject(self.promiseResult); // (E)

  26.         };

  27.     }

  28.     ...

  29.     return returnValue; // (F)

  30. };




    then() 创建并返回一个新的 promises(在 A 处和 F 处)。此外,fulfilledTask 和 rejectedTask 以不同方式设置:在处理结束时。
        1. onFulfilled 的结果被用在通过 returnValue(在 B 处)。如果 onFulfilled 为缺失的,我们使用通过的值来处理 returnValue(在 C 处)。
        2. onRejected 的结果被用于通过(并非拒绝) returnValue(在 D 处)。如果,onRejected 缺失,我们使用拒绝的值来拒绝 returnValue(在 E 处)。


    13.3 扁平化

    
    扁平化思想主要是使链式方式更为便捷:一般,将一个 reaction 返回的值传递到下一个 then()。如果我们返回一个 promise,不包裹的形式是最好的,像下面的例子:

  1. asyncFunc1()

  2. .then(function (value1){


  3.     return asyncFunc2(); // A

  4. })

  5. .then(function (value2){


  6.     // value2 为 asyncFunc2() promise 的通过状态。

  7.     console.log(value2);

  8. });




    我们在 A 处返回一个promise,就没有必要在当前方法中嵌套 then() 的调用,我们可以对方法的结果进行 then() 的调用。那么,不嵌套 then(),就保持扁平化。
    我们通过使 resolve() 方法扁平化来实现整体扁平化
        1. 以一个 promise Q 通过一个 promise P 意味着 Q 的处理结果要在 P 的 reactions 之前。
        2. 在 Q 中,P 应该被锁定:它不能被通过(或者拒绝)。并且它的状态和结果和 Q 的保持同步。


    如果我们使用 then式 (而非一个 promise)能以更通用的形式实现扁平化。


    浅谈ECMAScript 6下的promises API

    实现 锁住,我们需要使用一个布尔值标签 this.already 。一旦值为 true,this 将被锁住,不能在被通过,记录如果 this 仍在进行中,因为它的状态是和锁住的 promise 是一致的。



  1. DemoPromise.prototype.resolve = function (value) {


  2.     if (this.alreadyResolved) return;

  3.     this.alreadyResolved = true;

  4.     this._doResolve(value);

  5.     return this; // enable chaining

  6. };



    真实的解决代码在私有方法 _doResolve() 中:

  1. DemoPromise.prototype._doResolve = function (value) {


  2.     var self = this;

  3.     // Is `value` a thenable?

  4.     if (value !== null && typeof value === ‘object’

  5.         && ‘then’ in value) {


  6.         addToTaskQueue(function () {
     // (A)

  7.             value.then(

  8.                 function onFulfilled(value) {


  9.                     self._doResolve(value);

  10.                 },

  11.                 function onRejected(reason) {


  12.                     self._doReject(reason);

  13.                 });

  14.         });

  15.     } else {


  16.         this.promiseState = ‘fulfilled’;

  17.         this.promiseResult = value;

  18.         this._clearAndEnqueueReactions(this.fulfillReactions);

  19.     }

  20. };


    
    扁平化处理在 A 处进行:如果 value 为通过状态,那么当前 self 为通过状态,如果 value 为拒绝的,我们就希望 self 为拒绝状态。前面所述通过私有方法 _doResolve 和 _doReject 来实现,通过 alreadyResolved 来绕开阻挡。
    

    13.4. 更详细的 Promise 状态

    由于链式形式,promises 的状态变得更为复杂


    浅谈ECMAScript 6下的promises API


    如果你只是使用 promises,你只需要以简单的视角来看待,忽略锁定就好。最主要的状态相关概念是“settledness”: 一个 promise 在被通过或者拒绝的时候被设置完毕。在一个 promise 被设置之后,将不再变化(状态为通过状态或者拒绝状态)。

    如果你希望先处理 promsie,然后再将其通过,这便会很难理解:
        1. 直观的说,‘resolved’(已处理)意味着不能再次被(直接)的处理。一个 promise 在只在即未被设置过也不在锁定的状态下被解决。引用下规范:一个未被处理的 promise 一般处在 pending 状态。一个已经处理的 promise 可能为 等待,通过或者拒绝状态。
        2. 处理中不一定会使其被设置:你可以通过一个 promise 以另一个状态为 pending的。
        3. 处理中现在包含拒绝:你可以拒绝一个 promise 通过一个拒绝的 promise 处理。


    13.5. 异常

    在我们不久的将来,我们将会在 user code 中以 rejections 形式处理异常。目前来说,user code 只代表 then 中的两个回调函数参数。


    浅谈ECMAScript 6下的promises API

    下面代码片段展现了我们在 onFulfilled 内部处理异常转到 拒绝状态 – 通过 A 处调用时的 try-catch 包裹。

  1. var fulfilledTask;

  2. if (typeof onFulfilled === ‘function’) {


  3.     fulfilledTask = function () {


  4.         try {


  5.             var r = onFulfilled(self.promiseResult); // (A)

  6.             returnValue.resolve(r);

  7.         } catch (e) {


  8.             returnValue.reject(e);

  9.         }

  10.     };

  11. } else {


  12.     fulfilledTask = function () {


  13.         returnValue.resolve(self.promiseResult);

  14.     };

  15. }




    13.6. 揭示构造函数模式

    如果我们希望将 DemoPromise 转变为切实可用的 promise,我们还需要实现揭示构造函数模式:ES6 promises 不是通过方法来进行通过或者拒绝,而是通过监听在 executor 上的函数实现的,构造函数的参数。


    浅谈ECMAScript 6下的promises API

     如果执行函数抛出一个异常,该 promise 一定被拒绝。




 14. 两个常用的 promise 附加方法



    本段介绍一下两个在 ES6 中添加到 promsie 的方法。promise 库的大部分都支持他们。


    14.1. done()

    当你将数个 promise 方法链式调用时,你可能会无心之中忽略错误。看实例:

  1. function doSomeThing(){


  2.     asyncFunc()

  3.     .then(f1)

  4.     .catch(r1)

  5.     .then(f2); // A

  6. }




    如果在 A 处的 then() 生成拒绝状态,那么将不会被处理。 promise 库 Q 提供了一个方法 done(),放置在链式最后一个方法调用的后面。其或者替换最后一个 then()(也有一个到两个参数):

  1. function doSomeThing(){


  2.     asyncFunc()

  3.     .then(f1)

  4.     .catch(r1)

  5.     .done(f2);

  6. }




    又或者仅仅是插到最后一个 then() 之后(无参数):


  1. function doSomeThing(){


  2.     asyncFunc()

  3.     .then(f1)

  4.     .catch(r1)

  5.     .then(f2)

  6.     .done();

  7. }




    引用 Q 的文档:
        done 与 then 使用的黄金规则:既不返回任何一个 promise,或者结束链式调用,那么使用 done 来终止。使用 catch 来终止不是很好,因为 catch 的可能是其自己内部的错误。


    这也是在 ES6 中实现  done 的方式:

  1. Promise.prototype.done = function(onFulfilled, onRejected){


  2.     this.then(onFulfilled, onRejected)

  3.     .catch(function(reason){


  4.         setTimeout( ()=>{
     throw reason }, 0 );

  5.     });

  6. };




    虽然 done 功能极为有用,但是没有添加到 ES6 中,因为在将来这种检测可以被调试器自动调起(一个 ES 讨论版本中)。


    14.2. finally()

    有时你希望某个行为不管有没有错误抛出都立即执行。例如在一系列行为后的处理。这便是 promise 方法 finally() 所做的,极为类似与错误处理机制中的 finally 。其回调方法不接受参数,但是会有 通过状态或者拒绝状态的通知。

  1. createPeaource(...)

  2. .then(function(value1){
     ... })

  3. .then(function(value2){
     ... })

  4. .finally(function(){
     ... });




    这是 Domenic Denicola 计划实现的 finally():

  1. Promise.prototype.finally = function (callback) {


  2.     let p = this.constructor;

  3.     // 不在此调用回调函数,

  4.     // 希望使用 then 来处理

  5.     return this.then(

  6.         // Callback fulfills: 传递参数结果

  7.         // Callback rejects: 传递拒绝状态

  8.         value => p.resolve(callback()).then(() => value),

  9.         reason => p.resolve(callback()).then(() => {
     throw reason })

  10.     );

  11. };




    回调函数决定了 接收器(this)如何设置处理:
        1. 如果回调函数抛出一个错误或者返回一个拒绝状态的 promise,那么变为 拒绝状态的值。
        2. 否则,接收器的设置变为的 finally 返回的 promise 的设置。使用 finally() 的链式方法。


    例一:使用 finally() 来隐藏 spinner:

  1. showSpinner();

  2. fetchGalleryData()

  3. .then(data => updateGallery(data) )

  4. .catch(showNoDataError)

  5. .finnally(hideSpinner);




    例二:使用 finally 来清除测试

  1. var HTTP = require(‘q-io/http’);

  2. var server = HTTP.Server(app);

  3. return server.listen(0)

  4. .then(function(){
     ... })

  5. finally(server.stop);






 15. ES6 兼容的 promise 库


    下面有一些 promise 的库,有一些 ES6 的API,意味着你在将来也可以用原生 ES6 代码替换。
        1. RSVP.js 来自 Stefen Penner,为 ES6 promise API 的超集。
        2. Native Promise Only 来自 Kyle Simpson 是原生 ES6 promise 的 polyfill,以严格模式来定义,尽可能接近而不扩展。
        3. Lie 来自 Calvin Metcalf 小巧,完善的 promise 库,遵循 Promises/A+ 规范。
        4. Q.promise 来自 Kowal 实现 ES6 API。
        5. 最近的,来自 Paul Millr 包含 promise 的 ES6 Shim。




 16. 传统的异步代码的接口


    放你使用一个 promsie 库时,有时是基于不支持 promsie 的异步代码。这段讲述一下 Node.js 风格的异步函数与 jQuery deferreds。


    16.1 Node.js 的接口

    promise 库 Q 有几个工具方法来转换函数使其使用 Node.js 风格(err, result)的回调函数然后返回一个promise(还有一些做一些相反的事情,转换基于 promise 的函数来为一些接受回调函数的函数)。例如:

  1. var readFile = Q.denideify( FS.readFile );

  2. readFile(‘foo,txt’, ‘utf-8’)

  3. .then(function(text){


  4.     ....

  5. });




    denodify 为一个符合 ES6 promise API ,提供 nodification 函数式化功能。


    16.2. jQuery 的接口

    jQuery 的 deferred 类似于 promise,但是也有几个兼容性方面的不同。方法 then() 都类似与 ES6 promises(主要不同之处是:不会在 reactions 中监控错误抛出)。我们可以通过 Promise.resolve() 将 一个 jQuery deferred 为 ES6 的 promise:

  1. Promise.resolve(

  2.     jQuery.ajax({
    ...})

  3. ).then(funciton(data){


  4.     console.log(data);

  5. }).catch(function(reason){


  6.     console.error(reason)

  7. });








 17. 延伸阅读


    1. Promises/A+
http://promisesaplus.com/
:Brian Cavalier 与 Domenic Denicola 编辑(JS promise 事实标准)
    2. Javascript Promises:再次强势归来 http://www.html5rocks.com/en/tutorials/es6/promises/
:来自 Jake Archibad(挺不错的 promise 简要介绍)
    3. Promsie 反模式 http://taoofcode.net/promise-anti-patterns/
来自 Tao(要点与技术)
    4. Promise 模式 https://www.promisejs.org/patterns/
来自 Forbes Lindeasy
    5. 揭示构造函数模式 http://domenic.me/2014/02/13/the-revealing-constructor-pattern/
:来自 Domenic Denicola(为 Promise 构造函数使用的模式)
    6. Chrome 开发者工具调试异步 JS 代码 http://www.html5rocks.com/en/tutorials/developertools/async-call-stack/
:来自 Pearl Chen
    7. ES6 中的迭代器和生成器 http://www.2ality.com/2013/06/iterators-generators.html

 
原文地址:
  http://www.2ality.com/2014/10/es6-promises-api.html
原文作者:Dr. Axel Rauschmayer

























版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/221476.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月17日 下午6:00
下一篇 2026年3月17日 下午6:01


相关推荐

  • pycharm英语怎么读_PyCharm常用设置

    pycharm英语怎么读_PyCharm常用设置使用的是 PyCharm2018 3 4 代码的自动补全在 PyCharm 中找到 PowerSaveMod 选项 将前面的对勾去掉 在左上角 File 的展开栏的倒数第二行在 PyCharm 的最右下角有个 的样子 在 旁边 单击点开就可看到 PowerSaveMod 选项在这个 Currentinspe 中可以设置 Highlighting 即检查代码严格程度 过多的不

    2026年3月16日
    2
  • python获取财务数据_「净利润增长率」使用python获取股票“净利润同比增长率”等“上市公司成长能力”数据 – seo实验室…

    python获取财务数据_「净利润增长率」使用python获取股票“净利润同比增长率”等“上市公司成长能力”数据 – seo实验室…净利润增长率证券宝www.baostock.com是一个免费、开源的证券数据平台。提供大量准确、完整的证券历史行情数据、上市公司财务数据、实时证券行情推送服务等。通过PythonAPI获取证券数据信息,满足量化交易投资者、数量金融爱好者、计量经济从业者数据需求。本次介绍接口:获取季频成长能力数据:query_growth_data()(以下代码来自官网,侵删)方法说明:查询季频成长能力信息,可…

    2025年8月2日
    6
  • Linux查看文件夹大小

    Linux查看文件夹大小Linux 查看文件夹大小 1Linux 下查看文件和文件夹大小 1 1df 命令 1 2du 命令 1Linux 下查看文件和文件夹大小当磁盘大小超过标准时会有报警提示 这时如果掌握 df 和 du 命令是非常明智的选择 df 可以查看一级文件夹大小 使用比例 档案系统及其挂入点 但对文件却无能为力 du 可以查看文件及文件夹的大小 两者配合使用 非常有效 比如用 df 查看哪个一级目录过大 然后用 df 查看文件夹或文件的大小 如此便可迅速确定症结 下面分别简要介绍 1 1df 命令 可以用来查看分区的文

    2026年3月16日
    2
  • 微信火柴人html5小游戏,20个好玩的微信小游戏推荐!你玩过几个?「建议收藏」

    50000+游戏爱好者已加入我们!每天推荐好玩游戏!加入我们,沐沐带你发现好游戏!只有你想不到,没有我找不到的好游戏!「良心好游戏推荐」搜罗了好玩的微信小游戏大全,模拟经营游戏、恐怖游戏、消除游戏、休闲游戏、益智游戏、吃鸡游戏、烧脑游戏、解谜游戏大全、换装游戏、射击游戏、吃鸡小游戏、像素游戏一个都不少!还有游戏攻略哦!每天都会推荐好玩的小游戏。————————————————————————不知不…

    2022年4月11日
    96
  • 错误码

    错误码

    2026年3月12日
    4
  • 什么是CWPP

    什么是CWPP文章目录什么是 CWPP 云工作负载保护平台 CWPP 相关典型厂商安全狗参考什么是 CWPP 云工作保护平台 CloudWorkloa 简称 CWPP 自 2016 年到 2019 年连续四年 Gartner 的市场指南 MarketGuide 分析报告中可以看出这四年里面的 CWPP 产品的定义 基本产品特性以及厂商都发生了很大的变化 同时云安全炒作曲线 HypeCycle 也完成了从膨胀期到幻灭期的周期 在每年的云安全最酷厂商 CoolVendor 中也不断有 CWPP 厂商的

    2026年3月19日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号