JavaScript学习笔记

Promise对象

2019-11-27  本文已影响0人  钢笔先生

[20190512]

异步编程的一种解决方案。

对比对象:回调函数和事件。

对比结果:更合理更强大。

简单说,就是容器。里面保存着某个未来才会结束的事件。通常是异步操作。

Promise是一个对象,从它上面可以获得异步操作的消息。统一的API,各种异步操作都可以用同样的方法进行处理。

Promise对象的两大特点

Promise对象代表一个异步操作。有三种状态:

只有异步操作的结果才可以决定当前是哪种状态。其他操作都无法改变这个状态,即承诺,其他手段无法改变。

Promise状态改变的两种可能

单向数据流,一旦这两种状况之一发生,状态就凝固了,不会再变了,会一直保持这个结果,此时就成为resolved(已定型)

注意:如果改变已经发生,再对Promise对象添加回调函数,也会立即得到这个结果。

和事件的区别是,一旦事件错过了,再去监听是得不到结果的。

优点

有了Promise,就可以将异步操作以同步操作的流程表达出来,避免层层回调函数。

Promise对象还提供了统一的接口,使得控制异步操作更加容易了。

缺点

基本使用

下面这个就是基本使用框架:

const promise = new Promise(function(resolve, reject) {
    if (/* 异步操作成功 */) {
        resolve(value);
    } else {
        reject(error);
    }
});

注意,Promise构造函数接受一个函数作为参数,该函数的两个参数分别是:

这也是两个函数,由JavaScript引擎提供,不用自己部署。

resolve函数:pending --> fulfilled

Promise对象的状态从未完成变成成功

在异步操作成功时调用,并将异步操作的结果作为参数传递出去。

reject函数:pending --> rejected

异步操作失败时调用,将异步操作报出的错误作为参数传递出去。

promise.then分别指定两个状态的回调函数

promise.then(function(value) {
    // success
}, function(error) {
    // failure
});

需要在生成实例之后使用。第一个函数表示Promise对象变成resolved时调用,第二个回调函数在状态变为rejected时调用。

注:第二个函数是可选的。

两个函数的参数都是来自Promise对象传出的值。

function timeout(ms) {
    return new Promise((resolve, reject) => {
       setTimeout(resolve, ms, 'done'); 
    });
}

timeout(100).then((value) => {
    console.log(value);
})

注意done会作为resolve的参数。

Q: resolve函数到底要干嘛啊??

记住这个框架:异步操作执行完毕后,就调用resolve函数,否则就调用reject方法。

Promise实现Ajax

const getJSON = function(url) {
    const promise = new Promise((resolve, reject) => {
        const handler = function() {
            if (this.readyState !== 4) {
                return;
            }
            if (this.status == 200) {
                resolve(this.response);
            } else {
                reject(new Error(this.statusText));
            }
        }
        const client = new XMLHttpRequest();
        client.open('GET', url);
        client.onreadystatechange = handler;
        client.responseType = 'json';
        client.setRequestHeader('Accept', 'application/json');
        client.send();
    });
    return promise;
};

// 调用函数
getJSON('/posts.json').then(function(json) {
    console.log("Contents: " + json);
}, function(error) {
    console.error('出错了', error);
});

http://es6.ruanyifeng.com/#docs/promise

END.

上一篇 下一篇

猜你喜欢

热点阅读