-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
异步编程 and Promise #19
Comments
再探异步编程
PromisePromise解决了什么问题Promise 使用三个方面解决了回调地狱:
回调函数延迟绑定 Promise.resolve().then(onfulfilled,onreject) 在这里 返回值穿透Promise.resolve().then(() => {
return new Promise.resolve(1)
}).then() 在这个例子中,在then方法里面返回一个新的Promise,后面再通过 错误冒泡Promise.resolve().then(() => {
return new Promise.resolve(1)
}).then(() => {
return new Promise.resolve(2)
})
.then(() => {
return new Promise.resolve(3)
}).then(() => {
return new Promise.resolve(4)
})
.then(() => {
return new Promise.resolve(5)
})
.catch() 在多次链式调用之后,前面产生的错误会一直往后传递,知道被catch接受,避免频繁处理错误。 Promise为什么引入微任务Promise 是怎么解决回调呢,先假设三种方案:
方案对比
APIPromise.all() Promise.all()Promise.all() 方法接收一个promise的iterable类型(注:Array,Map,Set都属于ES6的iterable类型)的输入,并且只返回一个Promise实例, 那个输入的所有promise的resolve回调的结果是一个数组。这个Promise的resolve回调执行是在所有输入的promise的resolve回调都结束,或者输入的iterable里没有promise了的时候。它的reject回调执行是,只要任何一个输入的promise的reject回调执行或者输入不合法的promise就会立即抛出错误,并且reject的是第一个抛出的错误信息。 Promise.allSettled()该Promise.allSettled()方法返回一个在所有给定的promise都已经fulfilled或rejected后的promise,并带有一个对象数组,每个对象表示对应的promise结果。 当您有多个彼此不依赖的异步任务成功完成时,或者您总是想知道每个promise的结果时,通常使用它。 相比之下,Promise.all() 更适合彼此相互依赖或者在其中任何一个reject时立即结束。 Promise.any()Promise.any() 接收一个Promise可迭代对象,只要其中的一个 promise 成功,就返回那个已经成功的 promise 。如果可迭代对象中没有一个 promise 成功(即所有的 promises 都失败/拒绝),就返回一个失败的 promise 和AggregateError类型的实例,它是 Error 的一个子类,用于把单一的错误集合在一起。本质上,这个方法和Promise.all()是相反的。 Promise.race()Promise.race(iterable) 方法返回一个 promise,一旦迭代器中的某个promise解决或拒绝,返回的 promise就会解决或拒绝。 Promise.reject()Promise.reject()方法返回一个带有拒绝原因的Promise对象。 Promise.resolve()Promise.resolve(value)方法返回一个以给定值解析后的Promise 对象。如果这个值是一个 promise ,那么将返回这个 promise ;如果这个值是thenable(即带有"then" 方法),返回的promise会“跟随”这个thenable的对象,采用它的最终状态;否则返回的promise将以此值完成。此函数将类promise对象的多层嵌套展平。 Promise.prototype.then()then() 方法返回一个 Promise (en-US)。它最多需要有两个参数:Promise 的成功和失败情况的回调函数。 Promise.prototype.catch()catch() 方法返回一个Promise (en-US),并且处理拒绝的情况。它的行为与调用Promise.prototype.then(undefined, onRejected) 相同。 (事实上, calling obj.catch(onRejected) 内部calls obj.then(undefined, onRejected)). Promise.prototype.finally()finally() 方法返回一个Promise。在promise结束时,无论结果是fulfilled或者是rejected,都会执行指定的回调函数。这为在Promise是否成功完成后都需要执行的代码提供了一种方式。 模拟实现 Promise all 和 racefunction PromiseAll(promiseArr) {
return new Promise((resolve, reject) => {
let result = []
let len = promiseArr.length
if (len === 0) {
resolve(result)
return
}
const handData = (data, index) => {
result[index] = data;
if (len - index === 1) resolve(result)
}
for (let i = 0; i < len; i++) {
Promise.resolve(promiseArr[i]).then(data => {
// 因为传入的可能不是Promise对象,所以在Promise.resolve()中
handData(data, i)
}, err => {
reject(err)
})
}
})
} function PromiseRace(promiseArr) {
return new Promise((resolve, reject) => {
let len = promiseArr.length
if (len === 0) return
for (let i = 0; i < len; i++) {
Promise.resolve(promiseArr[i]).then(data => {
resolve(data)
return
}, err => {
reject(err)
return
})
}
})
} generator基本用法function* gen() {
yield 2;
yield 3;
}
let g = gen()
g.next()
// {value: 3, done: false} value 表示值,done表示该函数是否执行完 那么这种具有可以暂停函数的功能是怎么实现的呢 其实 generator 是协程的一种实现 什么是协程协程是一种比线程更加轻量级的存在,协程处在线程的环境中,一个线程可以存在多个协程,可以将协程理解为线程中的一个个任务。不像进程和线程,协程并不受操作系统的管理,而是被具体的应用程序代码所控制。 但有了协程并不意味着 js 有了 “多线程的能力”,当在切换到协程的时候,线程的执行权会交给协程,线程暂停 最佳实践const co = require('co');
function* gen() {
yield 1
}
let g = gen();
co(g).then(res => {
console.log(res);
}) 利用 async awaitasyncasync 是一个通过异步执行并隐式返回 Promise 作为结果的函数。 async function func() {
return 100;
}
console.log(func());
// Promise {<resolved>: 100} await先来看一段代码 async function test() {
console.log(100)
let x = await 200
console.log(x)
console.log(200)
}
console.log(0)
test()
console.log(300) 我们来分析一下这段程序。首先代码同步执行,打印出0,然后将test压入执行栈,打印出100, 下面注意了,遇到了关键角色await。 放个慢镜头: await 200; 被 JS 引擎转换成一个 Promise : let promise = new Promise((resolve,reject) => {
resolve(200);
}) 这里调用了 resolve,resolve的任务进入微任务队列。 然后,JS 引擎将暂停当前协程的运行,把线程的执行权交给父协程 promise.then(value => {
// 相关逻辑,在resolve 执行之后来调用
}) 根据 promise.then(value => {
// 1. 将线程的执行权交给test协程
// 2. 把 value 值传递给 test 协程
}) Ok, 现在执行权到了 最后的输出为 0
100
300
200
200 总结一下, 最后做一道 async function foo() {
console.log('foo')
}
async function bar() {
console.log('bar start')
await foo()
console.log('bar end')
}
console.log('script start')
setTimeout(function () {
console.log('setTimeout')
}, 0)
bar();
new Promise(function (resolve) {
console.log('promise executor')
resolve();
}).then(function () {
console.log('promise then')
})
console.log('script end') script start
bar start
foo
promise executor
script end
bar end
promise then
setTimeout 这里有个注意点,运行到await foo(),foo函数在resolve的时候,他自身的方法也调用了 |
初识
异步解决方案
try catch 是 genrate 和 co 的语法糖
为什么出现Promise,他解决了什么问题
优点:延迟传入函数、
PromiseAPI
Promise.then
Promise.catch
Promise.all[ ] 数组里面全部的Promise执行完成之后,这个Promise才会执行.then 有一个报错就会停止运行走Catch
Promise.some 有一个Promise改变状态后 整个Promise的状态就改变了
Promise.race
Promise.set...
手写PromiseAPI
Promise.all (并不能用)
The text was updated successfully, but these errors were encountered: