笔记 - Promise

285 阅读1分钟

Javascript的世界是单线程的,由此衍生了许多问题需要用异步解决,比如网络操作和浏览器事件。

以前这样的问题往往通过回调或AJAX解决,但 ES6 之后,Promise被列入语法规范,浏览器统一执行。

Promise

如果我们要用 AJAX 进行异步操作,可写作如下形式:

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

这么写 success 和 fail 都很明了,但当我需要多次异步操作时,就很难复用这段代码,每次 success, fail 的判定都是不一样的,需要整段复制。

Promise的基本形式可如: return new Promese(resolve,reject)=>{})

resolve 等同于 success
reject 等同于 fail

then(), catch()

借用廖雪峰老师的这段代码:

// 执行函数
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);
}

// Promise 对象
var p1 = new Promise(test);
var p2 = p1.then(function (result) {
    console.log('成功:' + result);
});
var p3 = p2.catch(function (reason) {
    console.log('失败:' + reason);
});

首先创建一个执行函数,写好 resolve 和 reject 的条件。
随后我们创建一个 Promise 对象,如果函数成功,使用 then()继续执行下一步。如果函数失败,则通过 catch() 抓住 error。

拼合之后:

new Promise(test).then(function (result) {
    console.log('成功:' + result);
}).catch(function (reason) {
    console.log('失败:' + reason);
});

Promise.all()

Promise.all() 方法接收一个 promise 的 iterable 类型(注:Array,Map,Set都属于ES6的 iterable 类型)的输入,该方法的作用是将多个Promise对象实例包装,生成并返回一个新的Promise实例。

promise 数组中所有的 promise 实例都变为 resolve 的时候,该方法才会返回,并将所有结果传递 results 数组中。promise 数组中任何一个 promise 为 reject 的话,则整个 Promise.all 调用会立即终止,并返回一个 reject 的新的 promise 对象。

let p1 = Promise.resolve(1),
    p2 = Promise.reject(2),
    p3 = Promise.resolve(3);
Promise.all([p1, p2, p3]).then(function (results) {
    //then方法不会被执行
    console.log(results); 
}).catch(function (e){
    //catch方法将会被执行,输出结果为:2
    console.log(2);
});

Promise.race()

Promise.race() 方法接收一个 promise 的 iterable 类型(注:Array,Map,Set都属于ES6的 iterable 类型)的输入,如果其中任意一个 promise 执行成功,返回 resolve 或者 reject, Promise.race() 也将返回 resolve 或者 reject。

const promise1 = new Promise((resolve, reject) => {
  setTimeout(resolve, 500, 'one');
});

const promise2 = new Promise((resolve, reject) => {
  setTimeout(resolve, 100, 'two');
});

Promise.race([promise1, promise2]).then((value) => {
  console.log(value);
  // Both resolve, but promise2 is faster
});

如上所示,promise1 与 promise2 进行竞速,100ms < 500ms,则 promise2 被返回。