Promise学习总结

2021-01-27  本文已影响0人  阿鲁提尔

了解promise诞生的历史背景


1.词语本意解释

promise [ˈprɑ:mɪs] 许诺;允诺;(有可能)
从字面意思,表示一个将来的状态。
用在异步操作里面,帮我们去处理一件未来可能发生的一件什么事。

2.MDN解释
3.按照用途来解释
4.为什么会有Promise?
5.为什么异步操作可以避免界面冻结呢?
6.异步操作的常见语法
document.getElementById('start').addEventListener('click', start, false);

function start() {
    // 响应事件,进行相应的操作
}

// jQuery 用 `.on()` 也是事件侦听
$('#start').on('click', start);
// 比较常见的有ajax
$.ajax('http://baidu.com', {
    success: function (res) {
        // 这里就是回调函数了
    }
});

// 或者在页面加载完毕后回调
$(function(){
    // 这里也是回调函数
});
7.浏览器中的JavaScript
8.有了Node.js之后

对异步的依赖进一步加剧了...
Node.js出现了的时候,PHP、JAVA、Python这些服务器端的语言都已经很成熟了。Node.js作为一个后来者,想要从中分一杯羹,必须有自己的绝活。

9.使用Node.js开发时的问题
a(function (resultsFromA) {
    b(resultsFromA, function (resultsFromB) {
        c(resultsFromB, function (resultsFromC) {
            d(resultsFromC, function (resultsFromD) {
                e(resultsFromD, function (resultsFromE) {
                    f(resultsFromE, function (resultsFromF) {
                        console.log(resultsFromF);
                    })
                })
            })
        })
    })
});
这段代码跑在node环境中,使用一些node模块。
const fs = require('fs');  //文件系统
const path = require('path');

function findLargest(dir, callback) {
    fs.readdir(dir, function (err, files) {
    //用fs.readdir读文件夹的内容。传入回调函数
        if (err) return callback(err); // [1]
        //如果发现错误,就用回调函数传出错误

        //如果读出来就执行下面操作
        let count = files.length; // [2]
        //取出来文件数量
        let errored = false;
        let stats = [];
        files.forEach( file => {  //对文件进行遍历
            fs.stat(path.join(dir, file), (err, stat) => {
            //每一个文件都用fs.stat去取状态。取出状态用到回调函数
                if (errored) return; // [1]
                //发生错误,中断,return掉
                if (err) {
                    errored = true;
                    return callback(err);
                }
                stats.push(stat); // [2]
                //没有发生错误,把stat文件放入数组

                if (--count === 0) {  //用count变量来计数,每读完一个文件,都减一,当到0的时候,就认为所有文件都读完了
                    let largest = stats  //然后对数组进行遍历,找出其中
                        .filter(function (stat) { return stat.isFile(); })
                        .reduce(function (prev, next) {
                            if (prev.size > next.size) return prev;
                            //找出其中最大的文件信息,用下面的callback返回
                            return next;  //记下内容
                        });
                    callback(null, files[stats.indexOf(largest)]);
                    //第一个参数,是否有参数,因为是正常的,所以返回null
                }
            });
        });
    });
}

findLargest('./path/to/dir', function (err, filename) {
//使用的时候调用,'传入要查找的目录',传入回调函数
//回调函数接受两个参数。“错误”,“文件名”
    if (err) return console.error(err);  
    //如果有错误,就返回错误信息。
    console.log('largest file was:', filename);
    //没有错误,返回文件名
});
//在标记的地方有问题,以后补充问题

异步回调有四个问题


Promise入门

1.Promise简介
new Promise(
    /* 执行器 executor */
    function (resolve, reject) {
        // 一段耗时很长的异步操作
        resolve(); // 数据处理完成
        reject(); // 数据处理出错
    }
)
    .then(function A() {
        // 成功,下一步
    }, function B() {
        // 失败,做相应处理
    });
2.Promise详解
3.Promise有三个状态:

Promise状态发生改变,就会触发.then()里的响应函数处理后续步骤
Promise状态一经改变,不会再变。


4.范例
console.log('here we go');
new Promise( resolve => {
    setTimeout( () => {
        resolve('hello');
    }, 2000);
})
    .then( value => {
        console.log( value + ' world');
    });

//输出结果
here we go
hello world  //2秒之后输出
5.两步执行范例
console.log('here we go');
new Promise( resolve => {
    setTimeout( () => {
        resolve('hello');
    }, 2000);
})
    .then( value => {
        console.log(value);
        return new Promise( resolve => {
            setTimeout( () => {
                resolve('world');
            }, 2000);
        });
    })
    .then( value => {
        console.log( value + ' world');
    });

//输出结果
here we go
hello  //2秒
world world  //2秒
6.已完成的Promise,再执行.then()
console.log('start');

let promise = new Promise(resolve => {
    setTimeout(() => {
        console.log('the promise fulfilled');
        resolve('hello, world');
    }, 1000);
});

setTimeout(() => {
    promise.then( value => {
        console.log(value);
    });
}, 3000);

//输出结果
start
the promise fulfilled  //1秒之后输出
hello, world  //再过2秒之后输出
7.在.then()的函数里面不返回新的Promise,会怎么样?
console.log('here we go');
new Promise(resolve => {
    setTimeout( () => {
        resolve('hello');
    }, 2000);
})
    .then( value => {
        console.log(value);
        console.log('everyone');
        (function () {
            return new Promise(resolve => {
                setTimeout(() => {
                    console.log('Mr.Laurence');
                    resolve('Merry Xmas');
                }, 2000);
            });
        }());
        return false;  //没有等待里面的promise执行
        //但是里面的定时器仍在等待执行
        //在promise里面如果不直接返回一个promise实例
        //就会默认执行下一个环节
        //即使返回false也不影响下一组,false作为直接传递到下一组
    })
    .then( value => {
        console.log(value + ' world');
    });

//输出结果
here we go  //先输出

hello  //这三个同时输出
everyone
false worl

Mr.Laurence  //最后输出这个
8.then()

小测试

1. .then()里有.then()的情况
console.log('start');
new Promise( resolve => {
    console.log('Step 1');
    setTimeout(() => {
        resolve(100);
    }, 1000);
})
    .then( value => {
        return new Promise(resolve => {
            console.log('Step 1-1');
            setTimeout(() => {
                resolve(110);
            }, 1000);
        })
            .then( value => {
                console.log('Step 1-2');
                return value;
            })
            .then( value => {
                console.log('Step 1-3');
                return value;
            });
    })
    .then(value => {
        console.log(value);
        console.log('Step 2');
    });

//输出结果
start
Step 1

Step 1-1
Step 1-2
Step 1-3

Step 2

学会使用promise解决异步回调带来的问题

掌握promise的进阶用法

上一篇 下一篇

猜你喜欢

热点阅读