-
Notifications
You must be signed in to change notification settings - Fork 4
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
即将彻底掌握 Promise #25
Comments
作为参数的 Promise 实例,自己定义了catch方法,那么它一旦被rejected,并不会触发Promise.all()的catch方法。 const p1 = new Promise((resolve, reject) => {
resolve('hello');
})
.then(result => result)
.catch(e => e);
const p2 = new Promise((resolve, reject) => {
throw new Error('报错了');
})
.then(result => result)
.catch(e => e);
Promise.all([p1, p2])
.then(result => console.log(result))
.catch(e => console.log(e));
// ["hello", Error: 报错了] 上面代码中, 如果 |
如何取消一个promise<button id="start">开始一个promise</button>
<button id="cancel">取消它</button> let cancelReason = 'cancel'
let controller
function race(p) {
let obj = {}
let p1 = new Promise((resolve, reject) => {
obj.resolve = resolve
obj.reject = reject
})
obj.promise = Promise.race([p, p1])
return obj
}
document.querySelector('#start').onclick = function () {
console.log('开始');
let _promise = new Promise(resolve => {
setTimeout(() => {
resolve('hello')
}, 5000)
})
controller = race(_promise)
controller.promise.then(resolveValue => {
if (resolveValue === cancelReason) return
// resolve code
console.log('resolve! ' + resolveValue)
}, rejectValue => {
if (rejectValue === cancelReason) return
console.log('reject! ' + rejectValue)
})
}
document.querySelector('#cancel').onclick = function () {
console.log('取消了')
controller.resolve(cancelReason)
} |
promise解决了什么问题解决了异步问题,相对于之前的解决方案—回调函数和事件,更加的合理和强大。 promise的缺点
promise的使用
|
手动实现一个Promise简版: const PENDING = 'pending'
const FULFILLED = 'fulfilled'
const REJECTED = 'rejected'
class Aromise {
constructor(fn) {
this.state = PENDING
this.value = null
this.reason = null
this.onFulfilledCbs = []
this.onRejectedCbs = []
const resolve = value => {
// 使用macro-task机制,确保onFulfilled异步执行,
// 且在 then 方法被调用的那一轮事件循环之后的新执行栈中执行,
// 即将then的回调push到onFulfilledCbs后再执行。
setTimeout(() => {
if (this.state === PENDING) {
this.state = FULFILLED
this.value = value
this.onFulfilledCbs.forEach(cb => {
this.value = cb(this.value)
})
}
})
}
const reject = reason => {
setTimeout(() => {
if (this.state === PENDING) {
this.state = REJECTED
this.reason = reason
this.onRejectedCbs.forEach(cb => {
this.reason = cb(this.reason)
})
}
})
}
try {
fn(resolve, reject)
} catch (err) {
reject(err)
}
}
then (onFulfilled, onRejected) {
typeof onFulfilled === 'function' && this.onFulfilledCbs.push(onFulfilled)
typeof onRejected === 'function' && this.onRejectedCbs.push(onRejected)
return this
}
}
new Aromise((resolve, reject) => {
console.log('start');
setTimeout(() => {
resolve(223)
}, 2000)
})
.then(res => {
console.log(res)
}) |
Promise.all如果参数中 promise 有一个失败(rejected),此实例回调失败(reject),失败原因的是第一个失败 promise 的结果。 let t1 = new Promise((resolve,reject)=>{
resolve("t1-success")
})
let t2 = new Promise((resolve,reject)=>{
resolve("t2-success")
})
let t3 =Promise.reject("t3-error");
Promise.all([t1,t2,t3]).then(res=>{
console.log(res)
}).catch(error=>{
console.log(error)
})
//打印出来是t3-error |
定制Error对象Error 对象是ECMAScript的内建(build in)对象。 但是由于stack trace等原因我们不能完美的创建一个继承自 Error 的类,不过在这里我们的目的只是为了和Error有所区别,我们将创建一个 TimeoutError 类来实现我们的目的。 在ECMAScript6中可以使用 class 语法来定义类之间的继承关系。 class MyError extends Error{
// 继承了Error类的对象
} 为了让我们的 TimeoutError 能支持类似 error instanceof TimeoutError 的使用方法,我们还需要进行如下工作。 //TimeoutError.js
function copyOwnFrom(target, source) {
Object.getOwnPropertyNames(source).forEach(function (propName) {
Object.defineProperty(target, propName, Object.getOwnPropertyDescriptor(source, propName));
});
return target;
}
function TimeoutError() {
var superInstance = Error.apply(null, arguments);
copyOwnFrom(this, superInstance);
}
TimeoutError.prototype = Object.create(Error.prototype);
TimeoutError.prototype.constructor = TimeoutError; 我们定义了 TimeoutError 类和构造函数,这个类继承了Error的prototype。 它的使用方法和普通的 Error 对象一样,使用 throw 语句即可,如下所示。 var promise = new Promise(function () {
throw TimeoutError('timeout')
})
promise.catch(function (error) {
console.log(error instanceof TimeoutError) // true
}) 有了这个 TimeoutError 对象,我们就能很容易区分捕获的到底是因为超时而导致的错误,还是其他原因导致的Error对象了。 |
catch
返回的还是一个 Promise 对象,因为后面还可以接着调用then
方法。The text was updated successfully, but these errors were encountered: