Open puddlejumper26 opened 3 years ago
Promise 构造函数
是同步
执行的,promise.then 中的函数是异步执行
的
const promise = new Promise(function(resolve, reject) {
// ... some code
if (/* 异步操作成功 */){
resolve(value);
} else {
reject(error);
}
});
promise.then(onFulfilled, onRejected)
promise必须实现then方法(可以说,then就是promise的核心),而且then必须返回一个promise,同一个promise的then可以调用多次,并且回调的执行顺序跟它们被定义时的顺序一致
then可以接受另一个promise传入,也接受一个“类then”的对象或方法,即thenable对象
Promise实例
生成以后,可以用then
方法分别指定resolved
状态和rejected
状态的回调函数
then方法可以接受两个回调函数作为参数。第一个回调函数是Promise对象的状态变为resolved时调用,第二个回调函数是Promise对象的状态变为rejected时调用。其中,第二个函数是可选的
,不一定要提供。
promise.then(function(value) {
// success
}, function(error) {
// failure
});
异常
异常
, promise.catch(onRejected)
相当于
promise.then(null, onRrejected);
// 注意
// onRejected 不能捕获当前onFulfilled中的异常
promise.then(onFulfilled, onRrejected);
// 可以写成:
promise.then(onFulfilled)
.catch(onRrejected);
function taskA() {
console.log("Task A");
}
function taskB() {
console.log("Task B");
}
function onRejected(error) {
console.log("Catch Error: A or B", error);
}
var promise = Promise.resolve();
promise
.then(taskA)
.then(taskB)
.catch(onRejected) // 捕获前面then方法中的异常
//不使用Promise
http.get('some_url', function (id) {
//do something
http.get('getNameById', id, function (name) {
//do something
http.get('getCourseByName', name, function (course) {
//dong something
http.get('getCourseDetailByCourse', function (courseDetail) {
//do something
})
})
})
});
//使用Promise
function getUserId(url) {
return new Promise(function (resolve) {
//异步请求
http.get(url, function (id) {
resolve(id)
})
})
}
getUserId('some_url').then(function (id) {
//do something
return getNameById(id); // getNameById 是和 getUserId 一样的Promise封装。下同
}).then(function (name) {
//do something
return getCourseByName(name);
}).then(function (course) {
//do something
return getCourseDetailByCourse(course);
}).then(function (courseDetail) {
//do something
});
macrotasks
: script(整体代码),setTimeout,setInterval,setImmediate,I/O,UI rendering,event listner
microtasks
: process.nextTick, Promises, Object.observe, MutationObserver
//极简的实现
class Promise {
callbacks = [];
constructor(fn) {
fn(this._resolve.bind(this));
}
then(onFulfilled) {
this.callbacks.push(onFulfilled);
}
_resolve(value) {
this.callbacks.forEach(fn => fn(value));
}
}
//Promise应用
let p = new Promise(resolve => {
setTimeout(() => {
console.log('done');
resolve('5秒');
}, 5000);
}).then((tip) => {
console.log(tip);
})
Step 1
Step 2
Step 3
Step 4
等待1秒钟
Step 5
这里console出现 done
Step 6
Step 7
Step 8
这里console出现 5秒钟
Step 9
Step 10
Step 11
//极简的实现+链式调用
class Promise {
callbacks = [];
constructor(fn) {
fn(this._resolve.bind(this));
}
then(onFulfilled) {
this.callbacks.push(onFulfilled);
return this; <======
}
_resolve(value) {
this.callbacks.forEach(fn => fn(value));
}
}
let p = new Promise(resolve => {
setTimeout(() => {
console.log('done');
resolve('5秒');
}, 5000);
}).then(tip => {
console.log('then1', tip);
}).then(tip => {
console.log('then2', tip);
});
Step 1
Step2
Step 3
Step 4
这里要过5秒钟
Step 5
这里出现 done
Step 6
Step 7
Step 8
这里出现 then1 5秒钟
Step 9
Step 10
Step 11
这里出现 then2 5秒钟
Step 12
Step 13
Step 14
Step 15
4.4
能够解决这个问题//极简的实现+链式调用+延迟机制
class Promise {
callbacks = [];
constructor(fn) {
fn(this._resolve.bind(this));
}
then(onFulfilled) {
this.callbacks.push(onFulfilled);
return this;
}
_resolve(value) {
setTimeout(() => {//看这里
this.callbacks.forEach(fn => fn(value));
});
}
}
let p = new Promise(resolve => {
console.log('同步执行');
resolve('同步执行');
}).then(tip => {
console.log('then1', tip);
}).then(tip => {
console.log('then2', tip);
});
setTimeout(() => {
p.then(tip => {
console.log('then3', tip);
})
});
Step 1
Step 2
Step 3
Step 4
这里出现 同步执行
Step 5
Step 6
Step 7
Step 8
这里出现 then1 同步执行
Step 9
Step 10
Step 11
这里出现 then2 同步执行
Step 12
Step 13
Step 14
Step 15
Step 16
Step 17
Step 18
pending
, fulfilled
, rejected
.//极简的实现+链式调用+延迟机制+状态
class Promise {
callbacks = [];
state = 'pending';//增加状态
value = null;//保存结果
constructor(fn) {
fn(this._resolve.bind(this));
}
then(onFulfilled) {
if (this.state === 'pending') {//在resolve之前,跟之前逻辑一样,添加到callbacks中
this.callbacks.push(onFulfilled);
} else {//在resolve之后,直接执行回调,返回结果了
onFulfilled(this.value);
}
return this;
}
_resolve(value) {
this.state = 'fulfilled';//改变状态
this.value = value;//保存结果
this.callbacks.forEach(fn => fn(value));
}
}
let p = new Promise(resolve => {
console.log('同步执行');
resolve('同步执行');
}).then(tip => {
console.log('then1', tip);
}).then(tip => {
console.log('then2', tip);
});
setTimeout(() => {
p.then(tip => {
console.log('then3', tip);
})
});
Step 1
Step 2
Step 3
Step 4
Step 5
Step 6
这里出现 同步执行
Step 7
Step 8
Step 9
Step 10
Step 11
Step 12
Step 13
Step 14
Step 15
Step 16
Step 17
这里出现 then1 同步执行
Step 18
Step 19
Step 20
Step 21
Step 22
Step 23
这里出现 then2 同步执行
Step 24
Step 25
Step 26
Step 27
Step 28
Step 29
Step 30
这里出现 then3 同步执行
Step 31
Step 32
Step 33
Step 34
【以上的模型的问题】
因为是同一个实例,调用再多次 then 也只能返回相同
的一个结果下一个
Promise新的
Promise 实例,这是串行Promise的基础,是实现真正链式调用的根本新的Promise实例
let promiseCount = 1;
//完整的实现 测试Demo
class Promise {
callbacks = [];
name = '';
state = 'pending';//增加状态
value = null;//保存结果
constructor(fn) {
this.name = `Promse-${promiseCount++}`;
console.log('[%s]:constructor', this.name);
fn(this._resolve.bind(this));
}
then(onFulfilled) {
console.log('[%s]:then', this.name);
return new Promise(resolve => {
this._handle({
onFulfilled: onFulfilled || null,
resolve: resolve
});
});
}
_handle(callback) {
console.log('[%s]:_handle', this.name, 'state=', this.state);
if (this.state === 'pe`nding') {
this.callbacks.push(callback);
console.log('[%s]:_handle', this.name, 'callbacks=', this.callbacks);
return;
}
//如果then中没有传递任何东西
if (!callback.onFulfilled) {
callback.resolve(this.value);
return;
}
var ret = callback.onFulfilled(this.value);
callback.resolve(ret);
}
_resolve(value) {
console.log('[%s]:_resolve', this.name);
console.log('[%s]:_resolve', this.name, 'value=', value);
if (value && (typeof value === 'object' || typeof value === 'function')) {
var then = value.then;
if (typeof then === 'function') {
then.call(value, this._resolve.bind(this));
return;
}
}
this.state = 'fulfilled';//改变状态
this.value = value;//保存结果
this.callbacks.forEach(callback => this._handle(callback));
}
}
/**
* 模拟异步请求
* @param {*} url
* @param {*} s
* @param {*} callback
*/
const mockAjax = (url, s, callback) => {
setTimeout(() => {
callback(url + '异步请求耗时' + s + '秒');
}, 1000 * s)
}
new Promise(resolve => {
mockAjax('getUserId', 1, function (result) {
resolve(result);
})
}).then(result => {
console.log(result);
//对result进行第一层加工
let exResult = '前缀:' + result;
return exResult;
}).then(exResult => {
console.log(exResult);
});
当第一个 Promise 成功时,resolve 方法将其状态置为 fulfilled ,并保存 resolve 带过来的value。然后取出 callbacks 中的对象,执行当前 Promise的 onFulfilled,返回值通过调用第二个 Promise 的 resolve 方法,传递给第二个 Promise。
Step 1
Step 2
Step 3
Step 4
Step 5
Step 6
Step 7
Step 8
Step 9
console.log -- > [Promise-1]:constructor
Step 10
Step 11
Step 12
Step 13
这一步的结果
Step 14
Step 15
增加的 --> promise.html:52 [Promse-1]:_resolve
Step 16
增加的 --> promise.html:53 [Promse-1]:_resolve value= getUserId异步请求耗时1秒
Step 17
Step 18
Step 19
Step 20
Step 21
增加了 --> promise.html:36 [Promse-1]:_handle state= fulfilled
Step 22
Step 23
Step 24
Step 25
增加了 --> promise.html:86 getUserId异步请求耗时1秒
Step 26
Step 27
Step 28
Step 29
增加了 --> promise.html:52 [Promise-2]:_resolve
Step 30
增加了 --> promise.html:53 [Promse-2]:_resolve value= 前缀:getUserId异步请求耗时1秒
Step 31
Step 32
Step 33
Step 34
Step 35
增加了 --> promise.html:36 [Promse-2]:_handle state= fulfilled
Step 36
Step 37
Step 38
Step 39
增加了 --> promise.html:91 前缀:getUserId异步请求耗时1秒
Step 40
Step 41
Step 42
增加了 --> promise.html:52 [Promise-3]:_resolve
Step 43
增加了 --> promise.html:53 [Promise-3]:_resolve value = undefined
Step 44
Step 45
Step 46
Step 47
Step 48
Step 49
Step 50
Step 51
Step 52
Step 53
Step 54
Step 55
Step 56
Step 1
Step 2
Step 3
Step 4
Step 5
Step 6
Step 7
Step 8
Step 9
Step 10
Step 11
Step 12
Step 13
Step 14
Step 15
Step 16
Step 17
Step 18
Step 19
Step 20
Step 21
Step 22
Step 23
Step 24
Step 25
Step 26
Step 27
Step 28
Step 29
Step 30
Step 31
Step 32
Step 33
Step 34
Step 35
Step 36
Step 37
Step 38
Step 39
Step 40
Step 41
Step 42
Step 43
Step 44
Step 45
Step 46
Step 47
Step 48
Step 49
Step 50
Step 51
Step 52
Step 53
Step 54
Step 55
Step 56
Step 57
Step 58
Step 59
Step 60
Step 1
Step 2
Step 3
Step 4
Step 5
Step 6
Step 7
Step 8
Step 9
Step 10
Step 11
Step 12
Step 13
Step 14
Step 15
Step 16
Step 17
Step 18
Step 19
Step 20
Step 21
Step 22
Step 23
Step 24
Step 25
Step 26
Step 27
Step 28
Step 29
Step 30
Step 31
Step 32
Step 33
Step 34
Step 35
Step 36
Step 37
Step 38
Step 39
Step 40
Step 41
Step 42
Step 43
Step 44
Step 45
Step 46
Step 47
Step 48
Step 49
Step 50
Step 51
Step 52
Step 53
Step 54
Step 55
Step 56
Step 57
Step 58
Step 59
Step 60
const promise = new Promise((resolve, reject) => {
console.log(1)
resolve()
console.log(2)
})
promise.then(() => {
console.log(3)
})
console.log(4)
//运行结果:
1
2
4
3
同步执行
的,promise.then 中的函数是异步执行
的const promise1 = new Promise((resolve, reject) => {
setTimeout(() => {
resolve('success')
}, 1000)
})
const promise2 = promise1.then(() => {
throw new Error('error!!!')
})
console.log('promise1', promise1)
console.log('promise2', promise2)
setTimeout(() => {
console.log('promise1', promise1)
console.log('promise2', promise2)
}, 2000)
//运行结果:
promise1 Promise { <pending> }
promise2 Promise { <pending> }
Uncaught (in promise) Error: error!!!
promise1 Promise { <fulfilled>'success' }
promise2 Promise {
<rejected> Error: error!!!
at promise.then (...)
at <anonymous> }
https://juejin.cn/post/6844903509934997511 https://www.jianshu.com/p/52fda0f4003a
1.0 什么是 Promise
Promise 的特点
里面保存着某个未来才会结束的事件
(通常是一个异步操作)的结果pending
(进行中)、fulfilled
(已成功)rejected
(已失败)pending
->fulfilled
pending
->rejected
resolved
(已定型)Promise A+规范
Promise 优点
Promise 缺点
1.1 几种常见异步编程方案
E.g. Callback function
1.2 问题
1.3 Promise 处理多个相互关联的异步请求