You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
const promise = new Promise(function(resolve, reject) {
// Do the usual XHR stuff
var req = new XMLHttpRequest();
req.open('GET', url);
req.onload = function() {
// This is called even on 404 etc
// so check the status
if (req.status == 200) {
// Resolve the promise with the response text
resolve(req.response);
}
else {
// Otherwise reject with the status text
// which will hopefully be a meaningful error
reject(Error(req.statusText));
}
};
// Handle network errors
req.onerror = function() {
reject(Error("Network Error"));
};
// Make the request
req.send();
});
story.chapterUrls.forEach(function(chapterUrl) {
// Fetch chapter
getJSON(chapterUrl).then(function(chapter) {
// and add it to the page
addHtmlToPage(chapter.html);
});
})
// Start off with a promise that always resolves
var sequence = Promise.resolve();
// Loop through our chapter urls
story.chapterUrls.forEach(function(chapterUrl) {
// Add these actions to the end of the sequence
sequence = sequence.then(function() {
return getJSON(chapterUrl);
}).then(function(chapter) {
addHtmlToPage(chapter.html);
});
})
// Loop through our chapter urls
story.chapterUrls.reduce(function(sequence, chapterUrl) {
// Add these actions to the end of the sequence
return sequence.then(function() {
return getJSON(chapterUrl);
}).then(function(chapter) {
addHtmlToPage(chapter.html);
});
}, Promise.resolve())
The text was updated successfully, but these errors were encountered:
本文摘录及参考自:
1. JavaScript Promise:简介
2. Promise| MDN
3. Promise 对象
4. Promise - 廖雪峰的官方网站
5. 前端中的 Monad
6. Promise - The Modern Javascript Tutorial
1. Promise与事件侦听器的区别
Promise 有点类似于事件侦听器,但有以下两点区别:
PS: 事件对于同一对象上发生多次的事情(如 keyup、touchstart 等)非常有用。对于这些事件,实际您并不关注在添加侦听器之前所发生的事情。
2. Promise构造函数
Promise 构造函数包含一个参数(一个带有 resolve(解析)和 reject(拒绝)两个参数的回调)。在回调中执行一些操作(例如异步),如果一切都正常,则调用 resolve,否则调用 reject。
与普通旧版 JavaScript 中的 throw 一样,通常拒绝时会给出 Error 对象,但这不是必须的。Error 对象的优点在于它们能够捕捉堆叠追踪,因而易于调试。
如果在函数中抛出一个错误,那么该promise 状态为rejected。函数的返回值被忽略。
综上:Promise可能会有以下三种状态:
3. Promise中的Catch
正如我们之前所看到的,then() 包含两个参数:一个用于成功,一个用于失败(按照 promise 中的说法,即执行和拒绝):
您还可以使用 catch():
注意,以上两个代码示例行为并不相同,后者相当于:
两者之间的差异虽然很微小,但非常有用。Promise 拒绝后,将跳至带有拒绝回调的下一个 then()(或具有相同功能的 catch())。如果是 then(func1, func2),则 func1 或 func2 中的一个将被调用,而不会二者均被调用。但如果是 then(func1).catch(func2),则在 func1 拒绝时两者均被调用,因为它们在该链中是单独的步骤。看看下面的代码:
流程如下:

then方法返回的是一个新的Promise实例(注意,不是原来那个Promise实例)。因此可以采用链式写法,即then方法后面再调用另一个then方法。
Promise.prototype.catch方法是.then(null, rejection)或.then(undefined, rejection)的别名,用于指定发生错误时的回调函数。
4. Promise中的Finally
finally方法用于指定不管 Promise 对象最后状态如何,都会执行的操作。该方法是 ES2018 引入标准的。
5. 重复使用Promise
直到 getChapter 被调用,我们才下载 story.json,但是下次 getChapter 被调用时,我们重复使用 story romise,因此 story.json 仅获取一次。
6. resolve一个Promise
如果调用resolve函数和reject函数时带有参数,那么它们的参数会被传递给回调函数。reject函数的参数通常是Error对象的实例,表示抛出的错误;resolve函数的参数除了正常的值以外,还可能是另一个 Promise 实例,比如像下面这样。
上面代码中,p1和p2都是 Promise 的实例,但是p2的resolve方法将p1作为参数,即一个异步操作的结果是返回另一个异步操作。
注意,这时p1的状态就会传递给p2,也就是说,p1的状态决定了p2的状态。如果p1的状态是pending,那么p2的回调函数就会等待p1的状态改变;如果p1的状态已经是resolved或者rejected,那么p2的回调函数将会立刻执行。
上面代码中,p1是一个 Promise,3 秒之后变为rejected。p2的状态在 1 秒之后改变,resolve方法返回的是p1。由于p2返回的是另一个 Promise,导致p2自己的状态无效了,由p1的状态决定p2的状态。所以,后面的then语句都变成针对后者(p1)。又过了 2 秒,p1变为rejected,导致触发catch方法指定的回调函数。
注意,调用resolve或reject并不会终结 Promise 的参数函数的执行。
上面代码中,调用resolve(1)以后,后面的console.log(2)还是会执行,并且会首先打印出来。这是因为立即 resolved 的 Promise 是在本轮事件循环的末尾执行,总是晚于本轮循环的同步任务。
一般来说,调用resolve或reject以后,Promise 的使命就完成了,后继操作应该放到then方法里面,而不应该直接写在resolve或reject的后面。所以,最好在它们前面加上return语句,这样就不会有意外。
如果 Promise 状态已经变成resolved,再抛出错误是无效的。
上面代码中,Promise 在resolve语句后面,再抛出错误,不会被捕获,等于没有抛出。因为 Promise 的状态一旦改变,就永久保持该状态,不会再变了。
7. Promise.race()的作用
上面代码中,只要p1、p2、p3之中有一个实例率先改变状态,p的状态就跟着改变。那个率先改变的 Promise 实例的返回值,就传递给p的回调函数。
上面代码中,如果 5 秒之内fetch方法无法返回结果,变量p的状态就会变为rejected,从而触发catch方法指定的回调函数。
8. Promise构建顺序执行的序列
假设现在已有一个章节序列,如何按章节顺序下载并加载呢
forEach 不是异步的,因此我们的章节内容将按照下载的顺序显示,这就乱套了。
我们想要将 chapterUrls 数组转变为 promise 序列,这可通过 then() 来实现
我们可以使用
array.reduce
将上述代码整理如下:The text was updated successfully, but these errors were encountered: