【问题标题】:Sequential Loading Using Promises使用 Promise 顺序加载
【发布时间】:2015-08-19 23:38:57
【问题描述】:

我有一个异步调用数组,我想按顺序调用它们,这意味着我不想在第一个 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 实现。

【问题讨论】:

    标签: javascript promise ecmascript-6 bluebird es6-promise


    【解决方案1】:

    如果我是正确的,这个块是导致问题的原因:

        promise = promise.then(function() {
            createPromise(container, i);
        });
    

    createPromise 返回一个 Promise,但是在 then 内部你没有返回那个 Promise,所以它会假设 return undefined;(所有 js 函数的默认值),因此后续的 Promise 都不会等待前任在开始之前完成。尝试将其更改为:

        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>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-11
      • 2016-10-21
      • 1970-01-01
      • 1970-01-01
      • 2017-06-21
      • 2016-11-14
      • 1970-01-01
      相关资源
      最近更新 更多