前端开发那些事儿大前端

Promise & Generator

2021-04-25  本文已影响0人  丽__

为了解决回调地域问题,commonJS社区提出了Promise规范,在es5中被标准化,成为语言规范

image.png image.png
    "html-webpack-plugin": "^3.2.0",
    "webpack": "^4.41.2",
    "webpack-cli": "^3.3.10",
    "webpack-dev-server": "^3.9.0"
使用npx webpack-dev-server promise/01.js --open  只有可以自动打开浏览器F12查看运行结果

---package.json

const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    mode: 'none',
    stats: 'none',
    devtool: 'source-map',
    plugins: [
        new HtmlWebpackPlugin()
    ]
}
const promise = new Promise(function (resolve, reject) {
    // 这里用于“兑现”承诺
    // resolve(100); //成功
    reject(new Error('promise rejected')) //失败
})

promise.then(function (value) {
    console.log('resolved', value);
}, function (error) {
    console.log('rejected', error);
})

console.log('end')

输出结果


image.png
function ajax(url) {
    return new Promise(function (resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url);
        xhr.responseType = 'json'
        xhr.onload = function () {
            if (this.status === 200) {
                resolve(this.response)
            } else {
                reject(new Error(this.statusText))
            }
        }
        xhr.send();
    })
}

ajax('../promise/api/users.json').then(function (res) {
    console.log(res)
}, function (error) {
    console.log(error);
})

链式调用   then
ajax('../promise/api/users.json').then(function (value) {
    console.log(111);
}).then(function () {
    console.log(222);
}).then(function () {
    console.log(33);
})
// 从前往后依次执行

没一个then方法都是上一个then返回的promise对象添加状态明确过后的回调

ajax('../promise/api/usersd.json').then(function (value) {
    console.log(111);
}).catch(function (error) {
    console.log(error);
})

//成功
Promise.resolve('foo').then(function(value){
  console.log(value);
})

等价于

new Promise(function(resolve,refect){
  resolve('foo')
})

//失败
Promise.reject(new Error('rejected')).catch(function(error){
  console.log(error);
})


//相等
var promise =ajax('../promise/api/users.json')
var promise2 = Promise.resolve(promise)
console.log(promise === promise2);
// true

var promise = Promise.all([
    ajax('../promise/api/users.json'),
    ajax('../promise/api/users2.json'),
])

promise.then(function (values) {
    console.log(values);
}).catch(function (error) {
    console.log(error);
})


//其中有一个返回失败  整体都失败

ajax('../promise/api/url.json').then(value => {
    const urls = Object.values(value);
    const tasks = urls.map(url => ajax(url))
    return Promise.all(tasks)
}).then(values => {
    console.log(values); 
})
console.log('start');
setTimeout(()=>{
  console.log('setTimeout');
},0)
Promise.resolve().then(()=>{
    console.log('promise')
}).then(()=>{
    console.log('promise2');
}).then(()=>{
    console.log('promise3');
})
console.log('end');

//输出  结果
start
end
promise
promise2
promise3
setTimeout

回调队列中的问题称之为宏任务宏任务执行过程中可能临时加上一些额外的需求,可以选择作为一个新的宏任务进到队列中排队,也可以作为当前任务的微任务,直接在当前任务结束过后立即执行 ,Promise的回调会作为微任务执行,setTimeout作为宏任务执行。 微任务的目的是为了提高整体的响应能力,目前绝大多数异步调用都是作为宏任务执行,Promise & MutationBoserver,node中的process.nextTick都是微任务

// 生成器函数回顾

function* foo() {
    console.log("start");
    try {
        const res = yield 'foo'
        console.log(res);
    } catch (e) {
        console.log(e);
    }
}

const generator = foo();

const result = generator.next();
console.log(result);

generator.next('bar');

generator.throw(new Error('Generator error'))

输出结果


image.png

function ajax(url) {
    return new Promise(function (resolve, reject) {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', url);
        xhr.responseType = 'json'
        xhr.onload = function () {
            if (this.status === 200) {
                resolve(this.response)
            } else {
                reject(new Error(this.statusText))
            }
        }
        xhr.send();
    })
}


function* main() {
    try {
        const users = yield ajax('../promise/api/users.json')
        console.log(users);

        const users2 = yield ajax('../promise/api/users2.json')
        console.log(users2);
    } catch (e) {
        console.log(e)
    }
}


function co(generator) {
    const g = generator()

    function handleResult(result) {
        if (result.done) return
        result.value.then(data => {
            handleResult(g.next(data))
        }, error => {
            g.throw(error)
        })
    }
    handleResult(g.next())
}

co(main)


// co库:https://github.com/tj/co
async function main() {
    try {
        const users = await ajax('../promise/api/users.json')
        console.log(users);

        const users2 = await ajax('../promise/api/users2.json')
        console.log(users2);
    } catch (e) {
        console.log(e)
    }
}

//直接调用
main()
上一篇下一篇

猜你喜欢

热点阅读