const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'
function MyPromise(fn) {
const that = this
that.state = PENDING
that.value = null
that.resolvedCallbacks = []
that.rejectedCallbacks = []
// 待完善resolve和reject函数
// 待完善执行 fn 函数
}
复制代码
接下来咱们来完善 resolve 和 reject 函数,添加在 MyPromise函数体内部数组
function resolve(value) {
if (that.state === PENDING) {
that.state = RESOLVED
that.value = value
that.resolvedCallbacks.map(cb => cb(that.value))
}
}
function reject(value) {
if (that.state === PENDING) {
that.state = REJECTED
that.value = value
that.rejectedCallbacks.map(cb => cb(that.value))
}
}
复制代码
完成以上两个函数之后,咱们就该实现如何执行Promise中传入的函数了promise
try {
fn(resolve, reject)
} catch (e) {
reject(e)
}
复制代码
最后咱们来实现较为复杂的then函数bash
MyPromise.prototype.then = function(onFulfilled, onRejected) {
const that = this
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v
onRejected = typeof onRejected == 'function' ? onRejected : r => {
throw r
}
if (that.state === PENDING) {
that.resolvedCallbacks.push(onFulfilled)
that.rejectedCallbacks.push(onRejected)
}
if (that.state === RESOLVED) {
onFulfilled(that.value)
}
if (that.state === REJECTED) {
onRejected(that.value)
}
}
复制代码
// 该代码目前在简单版中会报错,只是做为一个透传的例子
Promise.resolve(4).then().then((value) => console.log(value))
复制代码
new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve(1)
},0)
}).then(value => {
console.log(value)
})
复制代码
以上就是简单版Promise的实现。异步
const PENDING = 'pending'
const RESOLVED = 'resolved'
const REJECTED = 'rejected'
function MyPromise(fn) {
const that = this
that.state = PENDING
that.value = null
that.resolvedCallbacks = []
that.resolvedCallbacks = []
function resolve(value) {
if (that.state === PENDING) {
that.state = RESOLVED
that.value = value
that.resolvedCallbacks.map(cb => cb(that.value))
}
}
function reject(value) {
if (that.state === PENDING) {
that.state = REJECTED
that.value = value
that.rejectedCallbacks.map(cb => cb(that.value))
}
}
try {
fn(resolve, reject)
} catch (e) {
reject(e)
}
}
MyPromise.prototype.then = function(onFulfilled, onRejected) {
const that = this
onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : v => v
onRejected = typeof onRejected === 'function' ? onRejected : r => {
throw r
}
if (that.state === PENDING) {
that.resolvedCallbacks.push(onFulfilled)
that.rejectedCallbacks.push(onRejected)
}
if (that.state === RESOLVED) {
onFulfilled(that.value)
}
if (that.state === REJECTED) {
onRejected(that.value)
}
}
// 此匿名函数接受两个参数resolve,reject
new MyPromise((resolve, reject) => {
setTimeout(() => {
resolve(1)
},0)
}).then(value => {
console.log(value)
})
复制代码
Promise A+ 惟有多写async
// then执行比Promise晚
// reject 拒绝当前服务
// 完善Promise状态 pending ---> fulfilled
// promise.all 全部的promise进行调用 原子操做
// race 只要有一个状态发生变化值就返回
function Promise (fn) {
var callback;
this.then = function (done) {
// callback赋值为回调函数function
callback = done
}
// 先执行resolve
function resolve (data) {
setTimeout(function () {
// 先执行了then,geicallback赋值
callback(data)
},0)
}
fn(resolve)
}
复制代码
使用函数
new Promise(function (resolve, reject) {
resolve("解决")
}).then(function (data) {
console.log(data)
})
复制代码
new Promise(function (resolve, reject) {
resolve("解决")
// 不会执行
setTimeout( () => {
resolve("解决1")
}, 2000)
}).then(function (data) {
console.log(data)
})
// 解决
复制代码
console.log(1)
new Promise(resolve => {
console.log(2)
resolve()
console.log(3)
}).then(() => {
console.log(4)
})
console.log(5)
// 1 2 3 4 5
复制代码
注意,调用resolve
或reject
并不会终结Promise
的参数函数的执行。 上面代码中,调用resolve()
后,console.log(3)
仍是会执行。 所以,最好在resolve
或reject
前面加上return
,这样就不会继续执行了。字体
Promise.prototype.finally() finally
方法用于指定无论Promise
对象最后状态如何,都会执行的操做。 Promise.all()
方法用于将多个Promise
实例,包装成一个新的Promise
实例。ui
Promise.resolve(value)
方法返回一个以给定值value
解析后的Promise
对象。若是该值为promise
,返回这个promise
;若是这个值是thenable
(即带有"then"方法
),返回的promise
会"跟随"这个thenable
的对象,采用它的最终状态;不然返回的promise
将以此值完成。此函数将类promise
对象的多层嵌套展平。this
Promise.resolve('foo')
.then(Promise.resolve('bar'))
.then(function (result) {
console.log(result)
})
// foo
var promise1 = Promise.resolve(123);
promise1.then(function(value) {
console.log(value); // 123
});
// 使用静态Promise.resolve方法
Promise.resolve("Success").then(function(value) {
console.log(value); // "Success" 此时的状态机为resolve
}, function(value) {
// 不会被调用
});
// resolve一个数组
var p = Promise.resolve([1,2,3]);
p.then(function(v) {
console.log(v[0]); // 1
});
复制代码
Resolve另外一个promise
此方法和Promise.resolve()嵌套 async await 一个道理spa
var original = Promise.resolve(33)
var cast = Promise.resolve(original)
cast.then(value => {
console.log('value' + value)
})
console.log('original === cast' + (original === cast))
/*
* 打印顺序以下,这里有一个同步异步前后执行的区别
* original === cast ? true
* value: 33
*/
复制代码
从上面的打印结果说明promise
嵌套promise
以后的值和promise
是等价的,所以在KOA2
中即便外层嵌套Promise.resolve()
但并不影响结果。Promise.resolve()方法是返回resolve
的状态机。
// Resolve一个thenable对象
var p1 = Promise.resolve({
then: function(onFulfill, onReject) { onFulfill("fulfilled!")}
})
console.log(p1 instanceof Promise) // true, 这是一个Promise对象
p1.then(function(v) {
console.log(v); // 输出"fulfilled!"
}, function(e) {
// 不会被调用
})
// Thenable在callback以前抛出异常
// Promise rejects
var thenable = { then: function(resolve) {
throw new TypeError('Throwing')
resolve("Resolving")
}}
var p2 = Promise.resolve(thenable);
p2.then(function(v) {
// 不会被调用
}, function(e) {
console.log(e); // TypeError: Throwing
})
// Thenable在callback以后抛出异常
// Promise resolves
var thenable = { then: function(resolve) {
resolve("Resolving");
throw new TypeError("Throwing");
}}
var p3 = Promise.resolve(thenable);
p3.then(function(v) {
console.log(v); // 输出"Resolving"
}, function(e) {
// 不会被调用
});
复制代码
Promise.all(iterable)方法返回一个Promise
实例,此实例在iterable
参数内全部的promise
都"完成(resolved
)"或参数中不包含promise
时回调完成(resolve
);若是参数中promise
有一个失败(rejected
),此实例回调失败(reject
),失败缘由的是第一个失败promise
的结果。
var promise1 = Promise.resolve(3)
var promise2 = 42
var promise3 = new Promise((resolve, reject) {
// setTimeout第三个之后的参数是做为第一个func()的参数传进去。
setTimeout(resolve, 100, 'foo')
})
Promise.all([promise1, promise2, promise3]).then((value) {
console.log(values) // [3, 42, "foo"]
})
复制代码
已完成(already resolved)
状态的Promise
。promise
,则返回一个异步完成(asynchronously resolved) Promise
。注意:Google Chrome 58 在这种状况下返回一个已完成(already resolved)
状态的 Promise
。处理中(pending)
的Promise
。这个返回的 promise
以后会在全部的promise
都完成或有一个promise
失败时异步地变为完成或失败。 见下方关于“Promise.all 的异步或同步”
示例。返回值将会按照参数内的promise
顺序排列,而不是由调用 promise
的完成顺序决定。// setTimeout
var doc=document.getElementById('div');
setTimeout(function(){
doc.style.color='red';
},10000,setTimeout(function(){
doc.style.color='black';
},5000));
复制代码
上面的结果是,div元素内的字体样式5秒后变黑,10秒后再变红。是否是很惊奇,由于第三个参数也是一个定时器,5后就会开启。和JQuery里面的animate()不一样,animate里面回调是执行了前面以后再执行后面的。
说明
此方法在集合多个 promise
的返回结果时颇有用。
完成(Fulfillment
): 若是传入的可迭代对象为空,Promise.all
会同步地返回一个已完成(resolved
)状态的promise
。 若是全部传入的 promise
都变为完成状态,或者传入的可迭代对象内没有 promise
,Promise.all
返回的 promise
异步地变为完成。 在任何状况下,Promise.all
返回的 promise
的完成状态的结果都是一个数组,它包含全部的传入迭代参数对象的值(也包括非 promise
值)。
失败/拒绝(Rejection
): 若是传入的promise
中有一个失败(rejected
),Promise.all
异步地将失败的那个结果给失败状态的回调函数,而无论其它 promise
是否完成。
实例
Promise.all
的使用 若是参数中包含非 promise
值,这些值将被忽略,但仍然会被放在返回数组中(若是 promise
完成的话):
var p = Promise.all([1,2,3]) // Promise { <state>: "fulfilled", <value>: Array[3] }
p.then(v => console.log(v)) // [1, 2, 3]
var p2 = Promise.all([1,2,3, Promise.resolve(444)]) // Promise { <state>: "fulfilled", <value>: Array[4] }
var p3 = Promise.all([1,2,3, Promise.reject(555)]) // Promise { <state>: "rejected", <reason>: 555 }
复制代码