【问题标题】:Javascript Promise not waiting to resolve before next Then()Javascript Promise 不等待在下一个 Then() 之前解决
【发布时间】:2019-01-27 22:31:31
【问题描述】:

有人知道为什么这不同步运行吗?最后一个承诺似乎在第一个承诺之前解决

...

var promise = Promise.resolve();
promise.then( () => {
    return new Promise((resolve, reject) => {
        var file1 = fileChooserCSV.files[0];
        var reader1 = new FileReader();
        reader1.onload = function(){
            var csv = reader1.result;
            csvJson = csvJSON(csv);
            resolve();
        };
        reader1.readAsText(file1);
    });
});



promise.then( () => {
    return new Promise((resolve, reject) => {
        var file2 = fileChooserConfig.files[0];
        var reader2 = new FileReader();
        reader2.onload = function(){
            var config = reader2.result;
            configJson = JSON.parse(config);
            resolve();
        };
        reader2.readAsText(file2);
    });
});


promise.then( () => {
    return new Promise((resolve, reject) => {
        console.log('end');
        resolve();
    });
});

阅读器的 onload 方法似乎从未执行过,尽管它们确实应该执行(有数据传递给它们),并且在它们被移动到 Promise 之前就这样做了。由于 onload 不运行 resolve() 永远不会触发 ether 进入下一个 then(),但最后一个 then() 确实执行...

如果这有什么不同,这段代码会在 chrome 扩展弹出窗口中运行吗?

非常感谢!

更新..

以经典的嵌套方式重构它可以正常工作

var file1 = fileChooserCSV.files[0];
    var reader1 = new FileReader();
    reader1.onload = function(){
        var csv = reader1.result;
        csvJson = csvJSON(csv);

        var file2 = fileChooserConfig.files[0];
        var reader2 = new FileReader();
        reader2.onload = function(){
            var config = reader2.result;
            configJson = JSON.parse(config);
            console.log('end');
        };
        reader2.readAsText(file2);
    };
    reader1.readAsText(file1);

【问题讨论】:

  • 您没有正确链接承诺以使承诺以特定顺序解决。
  • @zzzzBov 感谢您的建议。你会说它以何种方式没有正确链接?

标签: javascript asynchronous promise synchronization


【解决方案1】:

你试过 Promise.All().then... 那样

var promise = Promise.resolve(3);
Promise.all([true, promise])
    .then(function(values) {
        console.log(values); // [true, 3]
});

https://developer.mozilla.org/pt-BR/docs/Web/JavaScript/Reference/Global_Objects/Promise/all

【讨论】:

  • 好主意!实际上,我最终确实想到了这样做,而且更有意义。但仍然不能完全解释为什么原始代码似乎不起作用。
【解决方案2】:

在 JS 运行时中,'then' 被移动到另一个堆栈,并且仅在调用堆栈为空时执行。

例如,在这里你创建我创建一个Promise.resolve() 喜欢你。但请注意,它只有在整个代码执行完毕后才会执行。您将在屏幕上看到“53”而不是预期的“35”:

const promise = Promise.resolve(3)

promise.then(res => {
  document.write(res)
})

document.write(5)

'then' 存储在附加堆栈中,仅在稍后执行。

有关更多信息,请查看 this perfect explanation 表格 Barak Chemo。观看到 30:40。

希望对你有帮助

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-04-02
    • 1970-01-01
    • 1970-01-01
    • 2020-12-27
    • 1970-01-01
    • 2015-05-09
    相关资源
    最近更新 更多