Promise

Posted 风雨飘飘飘啊飘

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Promise相关的知识,希望对你有一定的参考价值。

javascript的世界中,所有代码都是单线程执行的。

由于这个‘缺陷’,导致JavaScript的所有网络操作、浏览器事件,都必须是异步执行。异步执行可以用回调函数实现:

     function callback(){
            console.log(‘Done‘);
        }
        console.log(‘before setTimeout()‘);
        setTimeout(callback,1000);//1秒钟后调用callback函数
        console.log(‘after setTimeout()‘);

观察上述代码执行,在Chrome的控制台输出可以看到:

brfore setTimeout()

after setTimeout()

(等待1秒后)

Done

可见,异步操作会在将来的某个时间点触发一个函数调用。

AJAX就是典型的异步操作。以上一节代码为例:

    request.onreadstatechange = function() {
            if(request.readyState === 4){
                if(request.status == 200) {
                    return success(request.responseText);
                } else {
                    return fail(request.status);
                }
            }
        }

把回调函数success(request.responseText)和fail(request.status)写到一个AJAX操作里很正常,但是不好看,而且不利于代码复用。

写成这样?

   var ajax = ajaxGet(‘http://...‘);
        ajax.ifSuccess(success)
            .ifFail(fail);

这种链式写法的好处在于,先统一执行AJAX逻辑,不关心如何处理结果,然后,根据成功还是失败,在将来的某个时候调用success函数或者fail函数。这种“承诺将来会执行”的对象在JavaScript中称为Promise对象。

Promise有各种开源实现。在ES6中被统一规范,由浏览器直接支持。

例子:生成一个0-2之间的随机数,如果小于1,则等待一段时间后返回成功,否则返回失败:

    function test(resolve,reject) {
            var timeOut = Math.random()*2;
            log(‘set timeout to‘ + timeOut +‘seconds‘);
            setTimeout(function () {
                if(timeOut < 1){
                    log(‘call resolve()...‘);
                    resolve(‘200 OK‘);
                }
                else {
                    log(‘call reject()...‘);
                    reject(‘timeout in‘ + timeOut + ‘seconds‘);
                }
            },timeOut * 1000);
        }

这个test()函数有两个参数,这两个参数都是函数,如果执行成功,我们将调用resolve(‘200 OK‘),如果执行失败,我们将调用reject(‘timeout in ‘ + timeOut + ‘seconds‘)。可以看出,test()函数只关心自身的逻辑,并不关心具体的resolve和reject将如何处理结果。

有了执行函数,我们就可以用一个Promise对象来执行它,并在将来某个时刻获得成功或者失败的结果:

     var p1 = new Promise(test);
        var p2 = p1.then(function(result) {
            console.log(‘成功:‘ + result);
        });

        var p3 = p2.catch(function(reson) {
            console.log(‘失败:‘ + reason);
        });

变量p1是一个promise对象,它负责执行test函数。由于test函数在内部是异步执行的,当test函数执行成功时,我们告诉Promise对象。

    //如果成功,执行这个函数
        p1.then(function(result) {
            console.log(‘成功:‘ + result);
        });

当test函数执行失败时,我们告诉Promise对象:

 

以上是关于Promise的主要内容,如果未能解决你的问题,请参考以下文章

前端面试题之手写promise

什么时候然后从Promise.all()的子句运行?

Typescript编译器无法从Promise resolve调用中推断类型

前端片段整理

在 Promise 中包装 Auth0 的 parseHash 函数

在javascript承诺中执行的顺序是什么