while 循环中的承诺
Promises within while loop
我想知道我在 while 循环中得到一些承诺的行为的原因。
我有这段代码,所以它应该 运行 每个承诺只有在前一个承诺被解决之后。所以当我开始这个任务时,我写了这样的东西:
while (i <= totalImages) {
if (previousDeferred === null) {
previousDeferred = prepare(i);
}
else {
previousDeferred = previousDeferred.then(prepare(i));
}
// code to calculate i value
}
请注意,我的准备函数 returns 是在加载图像并执行其他一些逻辑时解析的承诺。但我注意到我的代码只是在等待第一个承诺被解决,然后所有下一个图像都立即下载。
我更改了我的代码并编写了 prepareImage 函数来分离逻辑,因此我收到了要下载的索引并且我在 while 循环中具有相同的逻辑。
function prepareImage(i) {
if (previousDeferred === null) {
previousDeferred = prepare(i);
}
else {
previousDeferred = previousDeferred.then(function(){
return prepare(i);
});
}
}
while (i <= totalImages) {
tryToPrepare(paths[i]);
// code to calculate i value
}
所以这是正常工作的,但我不知道第一个代码不起作用而第二个代码正常工作的原因,我认为这与 i 的值有关,也许 js 创建了链接当我使用包装函数时,因为它保留了它的值,并且当它知道它由于循环而改变时避免了链接,但我不太确定。
谁能帮我理解一下?
在第一个这行代码中:
previousDeferred = previousDeferred.then(prepare(i));
打电话给 prepare(i)
太早了。 .then()
希望您向它传递一个函数引用,.then()
基础架构稍后可以调用该函数引用。但是,按照上面的结构,您将立即调用 prepare(i)
并将该 return 值传递给 .then()
。这不是你想要的。
你的第二个版本:
previousDeferred = previousDeferred.then(function(){
return prepare(i);
});
正在正确传递函数引用,因此 prepare(i)
稍后可以由 promise 基础结构调用。我注意到您还使用包装函数对第二个函数进行了单独更改,以正确封装值 if i
,因此在调用 prepare(i)
之前它没有更改。这也是使这个版本工作所必需的。
仅供参考,您也可以使用 .bind()
作为快捷方式:
previousDeferred = previousDeferred.then(prepare.bind(null, i));
这将创建一个临时函数,稍后调用时将调用 prepare(i)
。这样做不需要包装函数,因为 i
的值是在正确的时间抓取并保存在绑定函数中供以后使用的。
我想知道我在 while 循环中得到一些承诺的行为的原因。
我有这段代码,所以它应该 运行 每个承诺只有在前一个承诺被解决之后。所以当我开始这个任务时,我写了这样的东西:
while (i <= totalImages) {
if (previousDeferred === null) {
previousDeferred = prepare(i);
}
else {
previousDeferred = previousDeferred.then(prepare(i));
}
// code to calculate i value
}
请注意,我的准备函数 returns 是在加载图像并执行其他一些逻辑时解析的承诺。但我注意到我的代码只是在等待第一个承诺被解决,然后所有下一个图像都立即下载。
我更改了我的代码并编写了 prepareImage 函数来分离逻辑,因此我收到了要下载的索引并且我在 while 循环中具有相同的逻辑。
function prepareImage(i) {
if (previousDeferred === null) {
previousDeferred = prepare(i);
}
else {
previousDeferred = previousDeferred.then(function(){
return prepare(i);
});
}
}
while (i <= totalImages) {
tryToPrepare(paths[i]);
// code to calculate i value
}
所以这是正常工作的,但我不知道第一个代码不起作用而第二个代码正常工作的原因,我认为这与 i 的值有关,也许 js 创建了链接当我使用包装函数时,因为它保留了它的值,并且当它知道它由于循环而改变时避免了链接,但我不太确定。
谁能帮我理解一下?
在第一个这行代码中:
previousDeferred = previousDeferred.then(prepare(i));
打电话给 prepare(i)
太早了。 .then()
希望您向它传递一个函数引用,.then()
基础架构稍后可以调用该函数引用。但是,按照上面的结构,您将立即调用 prepare(i)
并将该 return 值传递给 .then()
。这不是你想要的。
你的第二个版本:
previousDeferred = previousDeferred.then(function(){
return prepare(i);
});
正在正确传递函数引用,因此 prepare(i)
稍后可以由 promise 基础结构调用。我注意到您还使用包装函数对第二个函数进行了单独更改,以正确封装值 if i
,因此在调用 prepare(i)
之前它没有更改。这也是使这个版本工作所必需的。
仅供参考,您也可以使用 .bind()
作为快捷方式:
previousDeferred = previousDeferred.then(prepare.bind(null, i));
这将创建一个临时函数,稍后调用时将调用 prepare(i)
。这样做不需要包装函数,因为 i
的值是在正确的时间抓取并保存在绑定函数中供以后使用的。