【js进阶8】promise A+示例

JavaScript | 2020-09-12 14:29:05 779次 1次

一个 Promise 的当前状态必须为以下三种状态中的一种:等待态(Pending)、执行态(Fulfilled)和拒绝态(Rejected)。


Promises/A+ 译文地址


一、then 方法


2.2.1 onFulfilled 和 onRejected 都是可选的

promise.then(onFulfilled, onRejected) 


*1. 如果 onFulfilled 不是一个函数,则忽略

    let Pro = new Promise((resolve, reject)=>{
	setTimeout(()=>{
    	    resolve('success!')
	},500)
    })

    Pro.then(111,(err)=>{
    	console.log(err)
    })
    .then(222,(data)=>{
    	console.log(data)
    })
    .then((data)=>{
    	console.log(data) //success!
    })


*2. 如果 onRejected 不是一个函数,则忽略

    let Pro = new Promises((resolve, reject)=>{
	setTimeout(()=>{
            reject('error!')
	},500)
    })

    Pro.then(11,22)
    .then(111,222)
    .then(111, (data) => {
    	console.log(data)  //500ms后打印:error!
    })


2.2.2 如果 onFulfilled 是一个函数

*1. 必须在 promise fulfilled 后调用, 且 promise 的 value 为其第一个参数

    let Pro = new Promise((resolve, reject)=>{
	setTimeout(()=>{
            resolve('success!', 'other')
	},500)
    })

    Pro.then((val, other)=>{
	console.log(val, other) //500ms后打印:success!  undefined(第二个参数无效)
    })


*2. 它不能在 promise fulfilled 前调用

    let Pro = new Promise((resolve, reject)=>{
	setTimeout(()=>{
            resolve('success')
	}, 1000)
	console.time('fulfill')
    })

    Pro.then((val)=>{
        //fulfill: 1001.4ms (至少需要1000ms后打印)会等待 resolve
	console.timeEnd('fulfill') 
    })


*3. 不能被多次调用 

    var promise = new Promise((resolve)=>{
	resolve(1) // 执行
	resolve(2) // 不执行
    });
    promise.then((value)=>{
	console.log(value) //1
    })


2.2.3 如果 onRejected 是一个函数

*1. 它必须在 promise rejected 后调用, 且 promise 的 reason 为其第一个参

*2. 它不能在 promise rejected 前调用

*3. 不能被多次调用 

...
和 2.2.2 标准一致,将 resolve 换成 rejected 测试即可
...


2.2.4 onFulfilled 和 onRejected 是在执行环境中仅包含平台代码时调用

 参照(事件循环)机制


2.2.5 onFulfilled 和 onRejected 必须作为函数来调用,没有 this 值

Promises.resolve(1).then(()=>{
    console.log(this)  //打印 window 对象  严格模式下为 undefined
})


2.2.6 同一个 promise 上的 then 方法可能会调用多次

*1. 当 promise fulfilled 后,所有 onFulfilled 都必须按照其注册顺序执行

*2. 当 promise rejected 后,所有 onRejected 都必须按照其注册顺序执行

    let i = 0;
    let Pro = new Promise((resolve, reject)=>{
	setTimeout(()=>{
            resolve('success!')
	},500)
    })

    Pro.then(()=>{
	console.log(i++) //0
    })
    Pro.then(()=>{
	console.log(i++) //1
    })
    Pro.then(()=>{
	console.log(i++) //2
    })


2.2.7 then 方法会返回一个全新的 promise

promise2 = promise1.then(onFulfilled, onRejected)


*1. 如果 onFulfilled 或 onRejected 返回了值 x, 则执行 resolve(promise2, x)

    let promise = new Promise((resolve)=>{
	resolve(1)
    });
    promise.then((value)=>{
	console.log(value) // 1
	return new Promise((resolve)=>{
            resolve(2)
	});
    }).then((value)=>{
	return value
    }).then(val => {
	console.log(val) //2
    })


*2. 如果 onFulfilled 或 onRejected 抛出了异常 e, 则 promise2 应当以 e 为 reason 被拒绝

    var promise = new Promises((resolve)=>{
	resolve(1)
    });
    
    promise.then((value)=>{
	throw new Error('error')
    }).then((value)=>{
	// 不执行
	console.log(value)
    }).catch(val => {
	console.log(val) //Error: error
    })


*3. 如果 onFulfilled 不是一个函数且 promise1 已经 fulfilled,则 promise2 必须以 promise1 的值 fulfilled

    let promise = new Promise((resolve)=>{
	resolve(1)
    });
    
    promise.then(11).then(val => {
	console.log(val) //1
    })


*4. 如果 onReject 不是一个函数且 promise1 已经 rejected, 则 promise2 必须以相同的 reason 被拒绝

    let promise = new Promise((resolve, reject)=>{
	reject('err')
    });
    
    promise.catch(11).catch(val => {
	console.log(val) //err
    })


二、Promise 解析过程


2.3 Promise解析过程 是以一个promise和一个值做为参数的抽象过程,可表示为[[Resolve]](promise, x)


*1. 如果 promise 和 x 指向相同的值, 使用 TypeError 做为原因将 promise 拒绝

const promise = Promise.resolve().then(()=>{
    return promise;
});

promise.catch(console.error); // Chaining cycle detected for promise #<Promise>


*2. 如果 x 为 Promise ,则使 promise 接受 x 的状态

     ** 1. 如果 x 处于等待态, promise 需保持为等待态直至 x 被执行或拒绝

     ** 2. 如果 x 处于执行态,用相同的值执行 promise

     ** 3. 如果 x 处于拒绝态,用相同的据因拒绝 promise

let promise1 = new Promise((resolve) => {
    setTimeout(() => {
        resolve(666)
    }, 5000)
});

console.time('fulfill')
let promise = new Promise((resolve) => {
    // 等待 promise1 
    resolve(promise1)
})
promise.then((value) => {
    console.timeEnd('fulfill')
    // 3s后打印 666
    console.log('fulfill', value)
})

// 状态为 pending,等待 x(promise1)
setTimeout(()=>{
    console.log('setTimeout', promise)
}, 1000)
// 状态变为为 resolved
setTimeout(()=>{
    console.log('setTimeout', promise)
}, 6000)


*3. 如果 value 是一个对象或函数

    ** 1. 使 then 等于 value.then

    ** 2. 如果取 x.then 的值时抛出错误 e ,则以 e 为据因拒绝 promise

new Promise((resolve) => {
    resolve(0)
}).then(() => {
    return {
	then: (() => {
            throw new Error(11111111)
	})()
    }
}).then(res => {
    console.log(res)
}).catch(e => {
    console.log(e) // error 11111111
})

    ** 3. 如果 then 是一个函数,则把 value 作为函数中 this 指向来调用它,第一个参数是 resolvePromise,第二个参数是rejectPromise

        ***1.  如果 resolvePromise 通过传入 y 来调用,则执行 resolve(promise, y)

new Promise((resolve)=>{
    resolve(0)
}).then(() => {
    return {
        then:(resolvePromise, rejectPromise)=>{
            resolvePromise(5)
	}
    }
}).then((value)=>{
    console.log(value) // 5
})

               ***2.  如果 rejectPromise 通过传入原因 r 来调用,则传入 r 来 reject promise

new Promise((resolve)=>{
    resolve(0)
}).then(() => {
    return {
        then:(resolvePromise, rejectPromise)=>{
            rejectPromise(new Error('error'))
	}
    }
}).then((value)=>{
    console.log(value)
}).catch(err => {
    console.log(err) // error
})

               ***3.  如果 resolvePromise 和 rejectPromise 都被调用,或其中一个被调用了多次,则以第一次调用的为准,并忽略之后的调用

new Promise((resolve)=>{
    resolve(0)
}).then(() => {
    return {
        then:(resolvePromise, rejectPromise)=>{
            rejectPromise(new Error('error'))
            resolvePromise(5)
	}
    }
}).then((value)=>{
    console.log(value)
}).catch(err => {
    console.log(err) // error
})

    ** 4. 如果调用 then 抛出异常 e 

          ***1.  如果 resolvePromise 或 rejectPromise 已经调用,则忽略它

new Promise((resolve)=>{
    resolve(0)
}).then(() => {
    return {
        then: (resolvePromise, rejectPromise)=>{
	    resolvePromise(5)
            throw new Error('error')
	}
    }
}).then((value)=>{
    console.log(value) // 5
}, (reason)=>{
    console.log(reason)
})

           ***2.  否则,则传入 e 来 reject promise

new Promise((resolve)=>{
    resolve(0)
}).then(() => {
    return {
        then: (resolvePromise, rejectPromise)=>{
            throw new Error('error')
	}
    }
}).then((value)=>{
    console.log(value)
}, (reason)=>{
    console.log(reason) // error
})

     ** 5. 如果 then 不是函数,以 x 为参数执行 promis 

new Promise((resolve)=>{
    resolve()
}).then(res => {
    return {then:5}
}).then((value)=>{
    console.log(value) // {then:5}
}, (reason)=>{
    console.log(reason)
})


*4. 如果 x 不为对象或者函数,以 x 为参数执行 promise

new Promise((resolve)=>{
    resolve(5)
}).then((value)=>{
    console.log(value) // 5
}, (reason)=>{
    console.log(reason)
})

1人赞

分享到: