承诺是
(...)现在或将来可用或永不可用的值(来源:MDN)
所以我想说我有一个想要处理图片的应用程序。例如,加载图片在算法在后台(或其他类型的延迟)中使用它之后。现在我想检查一下,如果图片在将来中可用,则使用promise,而不是回调。
要检查,如果图像可用,我可以使用以下代码:
function loadImage(url) {
return new Promise((resolve, reject) => {
let image = new Image()
image.onload = function() {
resolve(image)
}
image.onerror = function() {
let message =
'Could not load image at ' + url
reject(new Error(msg))
}
image.src = url
})
}
属于此的承诺看起来像这样:
Promise.all([
loadImage('images/pic1.jpg'),
loadImage('images/pic2.jpg')
]).then((images) => {
images.forEach(img => addImg(img.src))
}).catch((error) => {
// handle error
})
这根本不会对我有所帮助,因为如果图片在现在中可用,而不是在将来中,则会查找承诺。图片将在一秒钟内存在,仍然承诺将返回错误。
我在这里没有得到什么承诺?对我来说,如果图片可用,它看起来像检查的整个未来方面取决于loadImage(url)
而不是实际的承诺本身。
PS:受funfunfunction启发的例子
承诺何时解决?
据我所知,它不会“监听”它周围的其他代码,更不用说可能在后台运行的框架了。我会假设在这个例子中它会像这样:承诺检查图片是否可用 - >他们仍然在后台工作 - >承诺解决并抛出错误 - >算法用图片完成 - >图片可用?
答案 0 :(得分:2)
JavaScript中的承诺有什么意义?
请参阅:You're Missing the Point of Promises。
无法考虑与单独使用Promise
相关的所有细微差别。浏览promise
标记,以阅读经常以promise
标记发布的用户发布的其他用户的问题和答案。在这些问题和答案的评论中询问有关具体案例的问题,以便进行自己的启发。
使用Promise
或.then()
获得.catch()
的值,而不是检查Promise
链之外的变量值。
无视“现在”和“未来”。专注于在.then()
和.catch()
中实施代码。引用标识符引用的异步值的所有其他代码将不可靠。
let id = void 0;
let promise = new Promise(resolve =>
setTimeout(() => {id = 123; resolve(id) }, Math.random() * 2000)
);
// this is not accurate
console.log(`id: ${id}`); // what is `id` here?
promise.then(res => console.log(`id: ${res}`));
另请注意,作为执行程序传递给Promise
构造函数的函数会立即调用
let id = void 0;
let promise = new Promise(resolve =>
setTimeout(resolve, Math.random() * 2000, id = 123)
);
// is this accurate?
console.log(`id: ${id}`); // what is `id` here?
promise.then(res => console.log(`id: ${res}`));
return
来自.then()
的值。
return
来自.then()
的值。使用.map()
代替.forEach()
Promise.resolve(123)
.then(data => console.log(data))
.then(res => console.log(res)) // `undefined`
Promise.resolve(123)
.then(data => { console.log(data); return data})
.then(res => console.log(res)) // `123`
使用.map()
代替.forEach()
let fn = (id) => new Promise(resolve =>
setTimeout(resolve, Math.random() * 2000, id)
);
Promise.all([1,2,3].map(fn))
.then(data => Promise.all(data.forEach(id => fn(id * 10))))
.then(data => console.log(`data: ${data}`)); // where is `data`
Promise.all([1,2,3].map(fn))
.then(data => Promise.all(data.map(id => fn(id * 10))))
.then(data => console.log(`data: ${data}`)); // `[10, 20, 30]`
已处理的拒绝或错误转换为已解决的Promise
不是throw
n或拒绝已退回
let fn = () => new Promise((resolve, reject) =>
setTimeout((id) => {reject(new Error(id)) }, Math.random() * 2000, 123)
)
fn().then(res => console.log(`id: ${res}`))
.catch(err => console.log(`err: ${err}`))
.then(res => console.log(`res: ${res}`)) // `undefined`
fn().then(res => console.log(`res: ${res}`))
.catch(err => { console.log(`err: ${err}`); return err })
// `.then()` is not called, function passed to `.catch()` is called
.then(res => console.log(`res: ${res}`))
.catch(err => console.log(`err: ${err}`)) // `123`