《JavaScript Promise迷你书》读书笔记

promise定义

Promise是笼统异步处置惩罚对象以及对其举行种种操纵的组件

简言之,运用Promise就是将javascript中异步的体式格局变换成同步来操纵。Promise则是把相似的异步处置惩罚对象和处置惩罚划定规矩举行规范化, 并根据采纳一致的接口来编写,划定要领以外的写法都邑报错。简朴的示例:

    var promise = getAsyncPromise("fileA.txt"); //处于Pending状况,既不是resolve也不是reject的状况。是promise对象刚被建立后的初始化状况
    promise.then(function(result){
        // 猎取文件内容胜利时的处置惩罚 胜利时状况为onFulfilled
    }).catch(function(error){
        // 猎取文件内容失利时的处置惩罚 失利时状况为onRejected
    });

个中,thencatch代表函数实行胜利和失利的预设操纵

构建promise对象,运用new关键字

    var promise = new Promise(function(resolve, reject) {
        // 异步处置惩罚
        // 处置惩罚完毕后、挪用resolve 或 reject
    });

对象要领 then

    promise.then(onFulfilled, onRejected); //onFulfilled函数会在promise对象的revolve状况挪用,onRejected为在promise对象reject状况下挪用
    promise.catch(function());//catch用来替代onRejected抛出毛病 

promise对象中内置部份静态要领

Promise.all() Promise.racePromise.resolve(),Promise.reject

建立XHR的promise对象

function getURL(URL) {
return new Promise(function (resolve, reject) {
    var req = new XMLHttpRequest();
    req.open('GET', URL, true);
    req.onload = function () {
        if (req.status === 200) {
            resolve(req.responseText);//传入resolve中的参数会在状况转变的时候,传到then中
        } else {
            reject(new Error(req.statusText));
        }
    };
    req.onerror = function () {
        reject(new Error(req.statusText));
    };
    req.send();
});
}
// 运转示例
var URL = "http://httpbin.org/get";
getURL(URL).then(function onFulfilled(value){
console.log(value);
}).catch(function onRejected(error){
console.error(error);
});

Promise.resolve

作用1. Promise.resolve 是 new Promise(func)的快捷体式格局,如Promise.resolve(42);new Promise(function(resolve){ resolve(42);});
作用2. 将thenable 对象转换为promise对象。thenable指的是一个具有 .then要领的对象。

Promise.reject

Promise.reject(new Error("出错了"))

等价于

new Promise(function(resolve,reject){
    reject(new Error("出错了"));
});

运用

Promise.reject(new Error("BOOM!")).catch(function(error){
    console.error(error);
});

promise对象马上进入resolve状况

var promise = new Promise(function (resolve){
    console.log("inner promise"); // 1
    resolve(42);
});
promise.then(function(value){
    console.log(value); // 3
});
console.log("outer promise"); // 2

输出效果为 1,2,3; 纵然resolve马上实行,得出的效果也鄙人一个时间环里,须要比及下一周期才实行

1.绝对不能对异步回调函数(纵然在数据已停当)举行同步挪用。
2.假如对异步回调函数举行同步挪用的话,处置惩罚递次能够会与预期不符,能够带来意料以外的效果。
3.对异步回调函数举行同步挪用,还能够致使栈溢出或非常处置惩罚紊乱等题目。
4.假如想在未来某时候挪用异步回调函数的话,能够运用 setTimeout 等异步API。

对照三段代码:

第一段:直接推断文件是不是加载完成

function onReady(fn) {
    var readyState = document.readyState;
    if (readyState === 'interactive' || readyState === 'complete') {
        fn();
    } else {
        window.addEventListener('DOMContentLoaded', fn);
    }
}
onReady(function () {
    console.log('DOM fully loaded and parsed');
});
console.log('==Starting==');

第二段:运用setTimeout转同步为异步操纵

function onReady(fn) {
    var readyState = document.readyState;
    if (readyState === 'interactive' || readyState === 'complete') {
        setTimeout(fn, 0); //运用setTimeout转化同步函数为异步函数
    } else {
        window.addEventListener('DOMContentLoaded', fn);
    }
}
onReady(function () {
    console.log('DOM fully loaded and parsed');
});
console.log('==Starting==');

第三段:运用promise的resolve将一致为异步的体式格局,削减推断

    function onReadyPromise() {
    return new Promise(function (resolve, reject) {
        var readyState = document.readyState;
        if (readyState === 'interactive' || readyState === 'complete') {
            resolve();
        } else {
            window.addEventListener('DOMContentLoaded', resolve);
        }
    });
}
onReadyPromise().then(function () {
    console.log('DOM fully loaded and parsed');
});
console.log('==Starting==');

关于通报参数promise的写法

function doubleUp(value) {
    return value * 2;
}
function increment(value) {
    return value + 1;
}
function output(value) {
    console.log(value);// => (1 + 1) * 2
}

var promise = Promise.resolve(1);//组织一个返回参数为1的promise对象
promise
    .then(increment) //此时increment函数中传的vaule值为1
    .then(doubleUp) //此时doubleUp函数中传的vaule值为2
    .then(output) //此时doubleUp函数中传的vaule值为 4
    .catch(function(error){
        // promise chain中出现非常的时候会被挪用
        console.error(error);
    });

Promise.resolvePromise.reject会对函数中return返回的值举行包装,终究then返回的效果都是新建立的promise对象

Promise.all的运用

function getURL(URL) {
    return new Promise(function (resolve, reject) {
        var req = new XMLHttpRequest();
        req.open('GET', URL, true);
        req.onload = function () {
            if (req.status === 200) {
                resolve(req.responseText);
            } else {
                reject(new Error(req.statusText));
            }
        };
        req.onerror = function () {
            reject(new Error(req.statusText));
        };
        req.send();
    });
}
var request = {
        comment: function getComment() {
            return getURL('http://azu.github.io/promises-book/json/comment.json').then(JSON.parse);
        },
        people: function getPeople() {
            return getURL('http://azu.github.io/promises-book/json/people.json').then(JSON.parse);
        }
    };
function main() {
    return Promise.all([request.comment(), request.people()]);
}
// 运转示例
main().then(function (value) {
    console.log(value);
}).catch(function(error){
    console.log(error);
});

证实Promise.all的promise数组是同时最先实行的

// `delay`毫秒后实行resolve
function timerPromisefy(delay) {
    return new Promise(function (resolve) {
        setTimeout(function () {
            resolve(delay);
        }, delay);
    });
}
var startDate = Date.now();
// 一切promise变成resolve后顺序退出
Promise.all([
    timerPromisefy(1),
    timerPromisefy(32),
    timerPromisefy(64),
    timerPromisefy(128)
]).then(function (values) {
    console.log(Date.now() - startDate + 'ms');
    // 约128ms
    console.log(values);    // [1,32,64,128]
});

Promise.race 只需有一个promise对象进入 FulFilled 或许 Rejected 状况的话,就会继续举行背面的处置惩罚

// `delay`毫秒后实行resolve
function timerPromisefy(delay) {
    return new Promise(function (resolve) {
        setTimeout(function () {
            resolve(delay);
        }, delay);
    });
}
// 任何一个promise变成resolve或reject 的话顺序就住手运转
Promise.race([
    timerPromisefy(1),
    timerPromisefy(32),
    timerPromisefy(64),
    timerPromisefy(128)
]).then(function (value) {
    console.log(value);    // => 1
});


//代码第二段 
var winnerPromise = new Promise(function (resolve) {
        setTimeout(function () {
            console.log('this is winner');
            resolve('this is winner');
        }, 4);
    });
var loserPromise = new Promise(function (resolve) {
        setTimeout(function () {
            console.log('this is loser');
            resolve('this is loser');
        }, 1000);
    });
// 第一个promise变成resolve后顺序住手
Promise.race([winnerPromise, loserPromise]).then(function (value) {
    console.log(value);    // => 'this is winner'
});

不能举行毛病处置惩罚的onRejected

function throwError(value) {
    // 抛出非常
    throw new Error(value);
}
// <1> onRejected不会被挪用
function badMain(onRejected) {
    return Promise.resolve(42).then(throwError, onRejected);
}
// <2> 有非常发作时onRejected会被挪用
function goodMain(onRejected) {
    return Promise.resolve(42).then(throwError).catch(onRejected);
}
// 运转示例
badMain(function(){
    console.log("BAD");
});
goodMain(function(){
    console.log("GOOD");
});

申明:上面代码中<1>中throwError 抛出了非常,onRejected 指定的函数也不会被挪用

.then 和 .catch 都邑建立并返回一个 新的 promise对象。 Promise实际上每次在要领链中增添一次处置惩罚的时候所操纵的都不是完全相同的promise对象。

    原文作者:pengj
    原文地址: https://segmentfault.com/a/1190000004391538
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞