使用 Promises 顺序加载
Sequential Loading Using Promises
我有一组异步调用,我想按顺序调用它们,这意味着我不想在第一个 promise 完成之前调用第二个 promise,依此类推。
在下面的示例中,我有一个循环可以动态创建独特的图像并将它们附加到页面。我希望图像按顺序附加,但由于某些原因,它们总是按照它们创建时的确切顺序呈现:
var container = document.getElementById("container");
var promise = Promise.resolve();
for(var i = 0; i<100; i++) {
(function(i) {
promise = promise.then(function() {
createPromise(container, i);
});
})(i);
}
function createPromise(container, i) {
return new Promise(function(resolve, reject) {
var img = new Image();
img.onload = function() {
container.appendChild(img);
resolve();
};
img.onerror = function() {
reject();
};
img.src = "http://placehold.it/100x100?text=Image+" + i + "&v=" + Date.now();
});
}
img { float: left; margin: 5px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/2.9.27/bluebird.min.js"></script>
<div id="container"></div>
我还创建了一个 Fiddle 来说明问题。
我正在使用 bluebird,但我更愿意坚持使用原生 ES6 实现。
如果我是正确的,则此块导致了问题:
promise = promise.then(function() {
createPromise(container, i);
});
createPromise
returns 一个承诺,但是在 then
内部你没有返回那个承诺,所以它会假设 return undefined;
(所有 js 函数的默认值)和因此 none 的后续承诺将等待前任完成后再开始。尝试将其更改为:
promise = promise.then(function() {
return createPromise(container, i);
});
var container = document.getElementById("container");
var promise = Promise.resolve();
for(var i = 0; i<100; i++) {
(function(i) {
promise = promise.then(function() {
return createPromise(container, i);
});
})(i);
}
function createPromise(container, i) {
return new Promise(function(resolve, reject) {
var img = new Image();
img.onload = function() {
container.appendChild(img);
resolve();
};
img.onerror = function() {
reject();
};
img.src = "http://placehold.it/100x100?text=Image+" + i + "&v=" + Date.now();
});
}
img { float: left; margin: 5px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/2.9.27/bluebird.min.js"></script>
<div id="container"></div>
我有一组异步调用,我想按顺序调用它们,这意味着我不想在第一个 promise 完成之前调用第二个 promise,依此类推。
在下面的示例中,我有一个循环可以动态创建独特的图像并将它们附加到页面。我希望图像按顺序附加,但由于某些原因,它们总是按照它们创建时的确切顺序呈现:
var container = document.getElementById("container");
var promise = Promise.resolve();
for(var i = 0; i<100; i++) {
(function(i) {
promise = promise.then(function() {
createPromise(container, i);
});
})(i);
}
function createPromise(container, i) {
return new Promise(function(resolve, reject) {
var img = new Image();
img.onload = function() {
container.appendChild(img);
resolve();
};
img.onerror = function() {
reject();
};
img.src = "http://placehold.it/100x100?text=Image+" + i + "&v=" + Date.now();
});
}
img { float: left; margin: 5px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/2.9.27/bluebird.min.js"></script>
<div id="container"></div>
我还创建了一个 Fiddle 来说明问题。
我正在使用 bluebird,但我更愿意坚持使用原生 ES6 实现。
如果我是正确的,则此块导致了问题:
promise = promise.then(function() {
createPromise(container, i);
});
createPromise
returns 一个承诺,但是在 then
内部你没有返回那个承诺,所以它会假设 return undefined;
(所有 js 函数的默认值)和因此 none 的后续承诺将等待前任完成后再开始。尝试将其更改为:
promise = promise.then(function() {
return createPromise(container, i);
});
var container = document.getElementById("container");
var promise = Promise.resolve();
for(var i = 0; i<100; i++) {
(function(i) {
promise = promise.then(function() {
return createPromise(container, i);
});
})(i);
}
function createPromise(container, i) {
return new Promise(function(resolve, reject) {
var img = new Image();
img.onload = function() {
container.appendChild(img);
resolve();
};
img.onerror = function() {
reject();
};
img.src = "http://placehold.it/100x100?text=Image+" + i + "&v=" + Date.now();
});
}
img { float: left; margin: 5px;}
<script src="https://cdnjs.cloudflare.com/ajax/libs/bluebird/2.9.27/bluebird.min.js"></script>
<div id="container"></div>