promise学习

来源:互联网 发布:手机海报制作软件 编辑:程序博客网 时间:2024/06/05 15:51

定义

promise代表一个异步操作的执行返回状态,这个执行返回状态在promise对象创建时未必已知。它允许你为异步操作的成功或失败指定处理方法。

表现

Promise是一种封装未来值的易于复用的异步任务管理机制。

术语

1. promise: 指一个拥有符合规范的 then方法的对象;2. thenable: 指一个定义了 then方法的对象;3. 决议(resolve): 改变一个promise等待状态至已完成或被拒绝状态, 一旦决议,不再可变;4. 值(value): 一个任意合法的JavaScript值,包括 undefined, thenable对象, promise对象;5. exception/error: JavaScript引擎抛出的异常/错误6. 拒绝原因(reject reason): 一个promise被拒绝的原因

promise只可能处于三种状态之一

- pending: 初始状态。 非 fulfilled 或 rejected。- resolved: 成功的操作。也有的成为fulfilled 。- rejected: 失败的操作。- 处于等待(pending)状态时,可以转变为已完成(fulfilled)或者被拒绝状态(rejected);- 处于已完成状态时,状态不可变,且需要有一个最终值;- 处于被拒绝状态时,状态不可变,且需要有一个拒绝原因。

THEN方法

1. 一个promise必须提供一个 then方法,以供访问其当前状态,或最终值或拒绝原因。2. 该方法接收两个参数,如 promise.then(onFulfilled, onRejected)3. onFulfilled: 在promise已完成后调用且仅调用一次该方法,该方法接受promise最终值作参数;4. onRejected: 在promise被拒绝后调用且仅调用一次该方法,该方法接受promise拒绝原因作参数;5. 该方法必须返回一个promise;
var promise = new Promise((resolve, reject) => {    setTimeout(function() {        resolve('完成');    }, 10);});promise.then((msg) => {    console.log('first messaeg: ' + msg);})promise.then((msg) => {    console.log('second messaeg: ' + msg);});

Promise.all()

  • 当所有promise都完成是,返回的promise完成,其最终值为由所有完成promsie的最终值组成的数组;
  • 当某一promise被拒绝时,则返回的promise被拒绝,其拒绝原因为第一个被拒绝promise的拒绝原因;
var p1 = new Promise((resolve, reject) => {    setTimeout(function(){        console.log('p1决议');        resolve('p1');    }, 10);});var p2 = new Promise((resolve, reject) => {    setTimeout(function(){        console.log('p2决议');        resolve('p2');    }, 10);});Promise.all( [p1, p2] ).then((msgs) => {    // p1和p2完成并传入最终值    console.log(JSON.stringify(msgs));}).then((msg) => {    console.log( msg );});

Promise.race(iterable)

race方法

返回一个promise,只要传入的诸多promise中的某一个完成或被拒绝,则该promise同样完成或被拒绝,最终值或拒绝原因也与之相同。
Promise.resolve(x)

resolve方法

  • 返回一个已决议的Promsie对象:
  • 若 x是一个promise或 thenable对象,则返回的promise对象状态同 x;
  • 若 x不是对象或函数,则返回的promise对象以该值为完成最终值;

reject()方法

  • 返回一个使用传入的原因拒绝的Promise对象。
var promise = new Promise((resolve, reject) => {    setTimeout(function() {        resolve('完成');    }, 10);});promise.then((msg) => {    console.log('first messaeg: ' + msg);    return msg + '第二次';}).then((msg) => {    console.log('second messaeg: ' + msg);});

promise实现

首先创建一个构造函数,供实例化创建promise,该构造函数接受一个函数参数,实例化时,会立即调用该函数,然后返回一个Promise对象:
var MyPromise = (() => {    var value = undefined; // 当前Promise    var tasks = []; // 完成回调队列    var rejectTasks = []; // 拒绝回调队列    var state = 'pending'; // Promise初始为等待态    // 辅助函数,使异步回调下一轮事件循环执行    var nextTick = (callback) => {        setTimeout(callback, 0);    };    // 辅助函数,传递Promsie的状态值    var ref = (value) => {        if (value && typeof value.then === 'function') {            // 若状态值为thenable对象或Promise,直接返回            return value;        }        // 否则,将最终值传递给下一个then方法注册的回调函数        return {            then: function(callback) {                return ref(callback(value));            }        }    };    var resolve = (val) => {};    var reject = (reason) => {};    function MyPromise(func) {        func(resolve.bind(this), reject.bind(this));    }    return MyPromise;});
  • 在实例化创建Promise时,我们会将构造函数的两个静态方法: resolve和 reject传入初始函数,接下来需要实现这两个函数:
var resolve = (val) => {    if (tasks) {        value = ref(val);        state = 'resolved'; // 将状态标记为已完成        // 依次执行任务回调        tasks.forEach((task) => {            value = nextTick((val) => {task[0](self.value);});        });        tasks = undefined; // 决议后状态不可变        return this;    }};var reject = (reason) => {    if (tasks) {        value = ref(reason);        state = 'rejected'; // 将状态标记为已完成        // 依次执行任务回调        tasks.forEach((task) => {            nextTick((reason) => {task[1](value);});        });        tasks = undefined; // 决议后状态不可变        return this;    }};
  • 目前构造函数,和静态方法完成和拒绝Promise都已经实现,接下来需要考虑的是Promise的实例方法和链式调用:
MyPromise.prototype.then = (onFulfilled, onRejected) => {    onFulfilled = onFulfilled || function(value) {        // 默认的完成回调        return value;    };    onRejected = onRejected || function(reason) {        // 默认的拒绝回调        return reject(reason);    };    if (tasks) {        // 未决议时加入队列         tasks.push(onFulfilled);         rejectTasks.push(onRejected);    } else {        // 已决议,直接加入事件循环执行         nextTick(() => {             if (state === 'resolved') {                 value.then(onFulfilled);             } else if (state === 'rejected') {                 value.then(onRejected);             }         });    }    return this;};
var promise = new MyPromise((resolve, reject) => {    setTimeout(() => {        resolve('完成');    }, 0);});promise.then((msg) => {console.log(msg);});