We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
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 任务同时执行,如果全部成功执行,则以数组的方式返回所有 Promise 任务的执行结果。 如果有一个 Promise 任务 rejected,则只返回 rejected 任务的结果。
多个 Promise 任务同时执行,返回最先执行结束的 Promise 任务的结果,不管这个 Promise 结果是成功还是失败。
多个 Promise 任务同时执行,等到所有promises都已敲定(settled)(每个promise都已兑现(fulfilled)或已拒绝(rejected))。返回一个promise,该promise在所有promise完成后完成。并带有一个对象数组,每个对象对应每个promise的结果。
多个 Promise 任务同时执行,当其中的一个 promise 成功,就返回那个成功的promise的值。
多个 Promise 任务同时执行,并将给定的失败信息传递给对应的处理方法。
返回一个状态由给定value决定的Promise对象。如果该值是thenable(即,带有then方法的对象),返回的Promise对象的最终状态由then方法执行决定; 否则的话(该value为空,基本类型或者不带then方法的对象),返回的Promise对象状态为fulfilled,并且将该value传递给对应的then方法。 通常而言,如果您不知道一个值是否是Promise对象,使用Promise.resolve(value) 来返回一个Promise对象,这样就能将该value以Promise对象形式使用。
实例方法,捕获异常,函数形式:fn(err){}, err 是 catch 注册 之前的回调抛出的异常信息。
Promise 注册回调函数,函数形式:fn(vlaue){},value 是上一个任务的返回结果,then 中的函数一定要 return 一个结果或者一个新的 Promise 对象,才可以让之后的then 回调接收。
添加一个事件处理回调于当前promise对象,并且在原promise对象解析完毕后,返回一个新的promise对象。回调会在当前promise运行完毕后被调用,无论当前promise的状态是完成(fulfilled)还是失败(rejected)
如果有个网络请求,我们一般会这么写
getUserInfo(function(res) { // do some thing })
如果再这个请求后的基础上,还要再发请求, 当请求变多了之后,就变成下面的样子:
getUserInfo(function() { getOrderList(function() { getOrderInfo(function() { getA(function() { getB(function() { // do some thing }) }) }) }) })
这就是江湖上令人闻风丧胆的”回调地狱“,它的缺点有:
那么我们能不能以更易阅读的同步方法来实现呢?promise 为我们提供了解决方案
const getUserInfo = function () { return new Promise((resolve, reject) => { setTimeout(function () { resolve(1); }, 1000); }); }; const getOrderList = function () { return new Promise((resolve, reject) => { setTimeout(function () { resolve(2); }, 100); }); }; const getOrderInfo = function () { return new Promise((resolve, reject) => { setTimeout(function () { resolve(3); }, 200); }); }; const getA = function () { return new Promise((resolve, reject) => { setTimeout(function () { resolve(4); }, 300); }); }; const getB = function () { return new Promise((resolve, reject) => { setTimeout(function () { resolve(5); }, 400); }); }; getUserInfo() .then((res) => { console.log(res); return getOrderList(); }) .then((res) => { console.log(res); return getOrderInfo(); }) .then((res) => { console.log(res); return getA(); }) .then((res) => { console.log(res); return getB(); }) .catch((err) => { console.log(err); }) .finally(() => { console.log("end"); }); 控制台打印结果: 1 2 3 4 end
这样确实要比回调地域好一些了,但是跟同步写法还有不太一样,那我们用async、await 同步写法优化一下
(async function useAsync() { try { const A = await getUserInfo(); console.log(A); const B = await getOrderList(); console.log(B); const C = await getOrderInfo(); console.log(C); const D = await getA(); console.log(D); const F = await getB(); console.log(F); } catch (error) { console.log("error:" + error); } })();
明白了promise的用法,那我们手动实现一个Promise试试
先写个简单的Promise:
function Promise(fn) { let callbacks = []; this.then = function (onResolved) { callbacks.push(onResolved); }; function resolve(value) { callbacks.forEach((cb) => { cb(value); }); } fn(resolve); } const getUserInfo = function () { return new Promise((resolve, reject) => { setTimeout(function () { resolve(1); }, 1000); }); }; getUserInfo().then((res) => { console.log(res); // 控制台输出:1 });
ok,现在还非常简陋,现在还不支持连续的调用then, 通过上面的文档我们可以知道,then是有返回一个promise的:
this.then = function (onResolved) { callbacks.push(onResolved); return this; }; // 调用 getUserInfo() .then((res) => { console.log(res); }) .then((res) => { console.log(2); }); 输出:1 2
对于promise而言,resolve才是执行函数的方法,那这样就需要保证在resolve之前,then方法中所有函数都已经push到数组里 这个条件,我们可以用setTimeout(fn, 0)实现,setTimeout(fn,0)的含义是,指定某个任务在主线程最早可得的空闲时间执行,也就是说,尽可能早得执行。它在"任务队列"的尾部添加一个事件,因此要等到同步任务和"任务队列"现有的事件都处理完,才会得到执行。 不懂可以看这里
function resolve(value) { setTimeout(function () { callbacks.forEach((cb) => { cb(value); }); }, 0); }
我们现在加几个请求,完善后,函数长这个样子:
function Promise(fn) { let callbacks = []; this.then = function (onResolved) { callbacks.push(onResolved); return this; }; function resolve(value) { setTimeout(function () { callbacks.forEach((cb) => { cb(value); }); }, 0); } fn(resolve); } const getUserInfo = function () { return new Promise((resolve, reject) => { setTimeout(function () { resolve(1); }, 100); }); }; const getOrderList = function () { return new Promise((resolve, reject) => { setTimeout(function () { resolve(2); }, 3000); }); }; const getOrderInfo = function () { return new Promise((resolve, reject) => { setTimeout(function () { resolve(3); }, 5000); }); }; getUserInfo() .then((res) => { console.log("res1:" + res); return getOrderList(); }) .then((res) => { console.log("res2:" + res); return getOrderInfo(); }) .then((res) => { console.log("res3:" + res); });
控制台会输出:res1:1 res2:1 res3:1, 现在有两个问题,1是返回值不对,2是没有按定时的时间点返回,二是几乎按顺序同时返回的 在resolve函数中加个返回值看下:
function resolve(value) { console.log(value) setTimeout(function () { callbacks.forEach((cb) => { cb(value); }); }, 0); }
输出:1 res1:1 res2:1 res3:1 2 3
因为resolve中的callbacks没有等前面定制器结束再执行,而是直接全部执行了,所以我们需要加入状态。
promise 中的状态有 pending、fulfilled、rejected。
pending可以转化为fulfilled或rejected并且只能转化一次,也就是说如果pending转化到fulfilled状态,那么就不能再转化到rejected。并且fulfilled和rejected状态只能由pending转化而来,两者之间不能互相转换。
加入状态后的代码长长这样:
function Promise(fn) { let state = "pending"; let callbacks = []; let value = null; function handle(handler) { if (state === "pending") { callbacks.push(handler); return; } let cb = state === "fulfilled" ? handler.onResolved : handler.onRejected, ret; if (cb === null) { cb = state === "fulfilled" ? handler.resolve : handler.reject; cb(value); return; } try { ret = cb(value); } catch (e) { handler.reject(e); return; } handler.resolve(ret); } this.then = function (onResolved, onRejected) { return new Promise(function (resolve, reject) { handle({ onResolved: onResolved || null, onRejected: onRejected || null, resolve: resolve, reject: reject }); }); }; function resolve(newValue) { if ( newValue && (typeof newValue === "object" || typeof newValue === "function") ) { var then = newValue.then; if (typeof then === "function") { then.call(newValue, resolve, reject); return; } } value = newValue; state = "fulfilled"; execute(); } function reject(reason) { state = "rejected"; value = reason; execute(); } function execute() { setTimeout(function () { callbacks.forEach(function (cb) { handle(cb); }); }, 0); } fn(resolve, reject); } const getUserInfo = function () { return new Promise((resolve, reject) => { setTimeout(function () { resolve(1); }, 100); }); }; const getOrderList = function () { return new Promise((resolve, reject) => { setTimeout(function () { reject(2); }, 1000); }); }; const getOrderInfo = function () { return new Promise((resolve, reject) => { setTimeout(function () { resolve(3); }, 1000); }); }; getUserInfo() .then((res) => { console.log("res1:" + res); return getOrderList(); }) .then( (res) => { console.log("res2:" + res); return getOrderInfo(); }, (res) => { console.log("res2 error:" + res); } ) .then((res) => { console.log("res3:" + res); });
感觉总结的不好,后来偶尔看到这篇 https://juejin.cn/post/6844903665686282253 ,作者总结的很清晰,有空再来改写一遍。
参考: https://mengera88.github.io/2017/05/18/Promise%E5%8E%9F%E7%90%86%E8%A7%A3%E6%9E%90/ https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise https://juejin.cn/post/6844903625609707534#heading-0 https://segmentfault.com/a/1190000013538587
The text was updated successfully, but these errors were encountered:
No branches or pull requests
目的
API
静态方法
Promise.all(iterable)
Promise.race(iterable)
Promise.allSettled(iterable)
Promise.any(iterable)
Promise.reject(reason)
Promise.resolve(value)
原型方法
Promise.prototype.catch(onRejected)
Promise.prototype.then(onFulfilled, onRejected)
Promise.prototype.finally(onFinally)
Promise解决了什么问题?
回调地域
如果有个网络请求,我们一般会这么写
如果再这个请求后的基础上,还要再发请求, 当请求变多了之后,就变成下面的样子:
这就是江湖上令人闻风丧胆的”回调地狱“,它的缺点有:
那么我们能不能以更易阅读的同步方法来实现呢?promise 为我们提供了解决方案
这样确实要比回调地域好一些了,但是跟同步写法还有不太一样,那我们用async、await 同步写法优化一下
明白了promise的用法,那我们手动实现一个Promise试试
手写Promise
先写个简单的Promise:
ok,现在还非常简陋,现在还不支持连续的调用then, 通过上面的文档我们可以知道,then是有返回一个promise的:
对于promise而言,resolve才是执行函数的方法,那这样就需要保证在resolve之前,then方法中所有函数都已经push到数组里
这个条件,我们可以用setTimeout(fn, 0)实现,setTimeout(fn,0)的含义是,指定某个任务在主线程最早可得的空闲时间执行,也就是说,尽可能早得执行。它在"任务队列"的尾部添加一个事件,因此要等到同步任务和"任务队列"现有的事件都处理完,才会得到执行。
不懂可以看这里
我们现在加几个请求,完善后,函数长这个样子:
控制台会输出:res1:1 res2:1 res3:1, 现在有两个问题,1是返回值不对,2是没有按定时的时间点返回,二是几乎按顺序同时返回的
在resolve函数中加个返回值看下:
输出:1 res1:1 res2:1 res3:1 2 3
因为resolve中的callbacks没有等前面定制器结束再执行,而是直接全部执行了,所以我们需要加入状态。
promise 中的状态有 pending、fulfilled、rejected。
pending可以转化为fulfilled或rejected并且只能转化一次,也就是说如果pending转化到fulfilled状态,那么就不能再转化到rejected。并且fulfilled和rejected状态只能由pending转化而来,两者之间不能互相转换。
加入状态后的代码长长这样:
感觉总结的不好,后来偶尔看到这篇 https://juejin.cn/post/6844903665686282253 ,作者总结的很清晰,有空再来改写一遍。
参考:
https://mengera88.github.io/2017/05/18/Promise%E5%8E%9F%E7%90%86%E8%A7%A3%E6%9E%90/
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Promise
https://juejin.cn/post/6844903625609707534#heading-0
https://segmentfault.com/a/1190000013538587
The text was updated successfully, but these errors were encountered: