学校门户网站功能外贸平台排名
承诺是一个简单的概念,即使您没有机会使用它们,您也可能已经阅读了它们。 它们是一种有价值的构造,它使异步代码能够以更具可读性的方式构造,而不是作为一堆嵌套的匿名函数。 本文涉及了您可能对诺言不了解的六件事。
在深入探讨该列表之前,这里快速提醒您一下JavaScript承诺的样子:
var p = new Promise(function(resolve, reject) {resolve("hello world");
});p.then(function(str) {alert(str);
});
1. then()
返回一个分叉的承诺
以下两个代码块有什么区别?
// Exhibit A
var p = new Promise(/*...*/);
p.then(func1);
p.then(func2);
// Exhibit B
var p = new Promise(/*...*/);
p.then(func1)
.then(func2);
如果您认为两个代码块都是等效的,则可能是在考虑promise只是回调的一维数组。 但是,实际上并非如此。 每次对then()
调用都会返回一个分叉的承诺。 因此,在图表A中,如果func1()
引发异常, func2()
仍将被正常调用。
在附件B中,如果func1()
引发异常,则不会调用func2()
,因为对then()
的首次调用返回了一个新的promise,但由于func1()
的异常而被拒绝。 结果是func2()
被跳过了。
要点:承诺可以像复杂的流程图一样进入多个路径。
2.回调应通过结果
当您运行以下代码时,会收到什么警报?
var p = new Promise(function(resolve, reject) {resolve("hello world");
});p.then(function(str) {})
.then(function(str) {alert(str);
});
第二个then()
中的警报不显示任何内容。 这是因为在promise的上下文中,回调与其说是结果的转换,不如说是回调。 Promise希望您的回调返回相同的结果或替换结果,然后将其传递给下一个回调。
这个想法类似于使用适配器转换结果,如以下示例所示。
var feetToMetres = function(ft) { return ft*12*0.0254 };var p = new Promise(/*...*/);p.then(feetToMetres)
.then(function(metres) {alert(metres);
});
3.仅捕获先前级别的异常
这两个代码块之间有什么区别:
// Exhibit A
new Promise(function(resolve, reject) {resolve("hello world");
})
.then(function(str) {throw new Error("uh oh");},undefined
)
.then(undefined,function(error) {alert(error);}
);
// Exhibit B
new Promise(function(resolve, reject) {resolve("hello world");
})
.then(function(str) {throw new Error("uh oh");},function(error) {alert(error);}
);
在附录A中,当一个异常中被抛出第一then()
它被夹在第二then()
和“嗯哦”被提醒。 这遵循仅捕获先前级别的异常的规则。
在图表B中,回调和错误回调处于同一级别,这意味着在回调中引发异常时,不会捕获该异常。 实际上,附件B的错误回调仅在promise为
处于拒绝状态或承诺本身引发异常。
4.可以从中恢复错误
在错误回调中,如果不重新引发错误,则promise将假定您已从错误中恢复并恢复为已解决状态。 在下面的示例中,显示“我已保存”,因为第一个then()
的错误回调未重新引发异常。
var p = new Promise(function(resolve, reject) {reject(new Error("pebkac"));
});p.then(undefined,function(error) { }
)
.then(function(str) {alert("I am saved!");},function(error) {alert("Bad computer!");}
);
承诺可以看作是洋葱上的一层。 每个then()
函数将另一层添加到洋葱上。 每一层代表一个可以处理的活动。 该层结束后,假定结果已固定并准备好用于下一层。
5.承诺可以暂停
仅仅因为您已经在then()
函数中执行了,并不意味着您不能暂停它来先完成其他事情。 要暂停当前的承诺,或让它等待另一个承诺的完成,只需从then()
内部返回另一个承诺。
var p = new Promise(/*...*/);p.then(function(str) {if(!loggedIn) {return new Promise(/*...*/);}
})
.then(function(str) {alert("Done.");
})
在先前的代码示例中,直到新的承诺解决后,警报才会显示。 这是在现有异步代码路径内引入其他依赖关系的便捷方法。 例如,您可能会发现用户会话已超时,并且您可能想在继续之前的代码路径之前启动辅助登录。
6.已解决的承诺不会立即执行
当您运行以下代码时,会收到什么警报?
function runme() {var i = 0;new Promise(function(resolve) {resolve();}).then(function() {i += 2;});alert(i);
}
您可能会认为它会发出警报2,因为Promise会立即解决,并且then()
函数会立即(同步)执行。 但是,promise规范要求所有调用必须强制异步以统一。 因此,在修改i
的值之前调用警报。
链接:
下载Promise / A + API的各种实现。
From: https://www.sitepoint.com/six-things-might-know-promises/