收集多个承诺结果?(普通javascript)

fru*_*ert 5 javascript es6-promise

我是Promises的新手,它尝试首先从localstorage加载很多结果,如果失败,请回过头从服务器获取数据。我不想使用jquery-忽略我当前正在使用$ .getJSON:-/

function loader1() {
    return new Promise(function (resolve, reject) {
        localforage.getItem("data1").then(function (value) {
            if (value !== null) {
                resolve(value);
            } else {
                $.getJSON("/myapp/data1.json").then(function (data) {
                    if (data !== null) {
                        resolve(data);
                    }
                }).catch(function (err) {
                    reject(err);
                });
            }
        });
    });
}
Run Code Online (Sandbox Code Playgroud)

一个文件就可以了。所以我会

loader1().then(function(result) { 
    // we have a result
    doSomethingElse();
}).catch(function (err) {
    // problem
});
Run Code Online (Sandbox Code Playgroud)

但是我想对多个文件执行此操作,其中一些文件位于本地存储中,而另一些文件则从远程源加载json。我想加载所有内容,并在完成后执行我的应用程序的下一步。

Promise.all看起来是这样,但是我看不到如何获得每个加载程序的结果;我以为会是这样的:

Promise
    .all([loader1, loader2, loader3])
    .then(function(result1,result2,result3)) {
        ...
Run Code Online (Sandbox Code Playgroud)

但这不是它的工作原理...所以我尝试了

Promise
    .all([loader1, loader2, loader3])
    .then(function(result)) {
        // var result1 = result[0];
        // var result2 = result[1];
        // var result3 = result[1];
Run Code Online (Sandbox Code Playgroud)

但是第二个的结果是函数而不是返回值...

在许多站点上搜索表明,诸如Q和bluebird之类的Promise系统具有一种spread类似于我想要的方法。可以使用普通的旧javascript来做到这一点(如何?),还是应该改用Q或RSVP之类的库?

gue*_*314 5

调用函数

Promise
.all([loader1(), loader2(), loader3()])
.then(function(result) {
  // var result1 = result[0];
  // var result2 = result[1];
  // var result3 = result[1];
 })
 .catch(function (err) {
   // problem
 });
Run Code Online (Sandbox Code Playgroud)

另请参见如何缓存使用脚本标记下载的已下载javascript文件


rab*_*tco 5

但是第二个的结果是函数而不是返回值...

您不会解析Promise您构造的任何值。您也不会.then从链中的后续值返回任何值。您需要对每个加载程序功能执行以下操作:

function loader1() {

    var data = localforage.getItem("data1");

    data.then(function (data) {

        if (data !== null) {
             return data;
        } else {
            data = $.getJSON("/myapp/data1.json")

            if (data !== null) {
                return data;
            } else {
                return Error;
        }

    data.catch(function (err) {
       return (err);
    }
Run Code Online (Sandbox Code Playgroud)

这确保了对函数loader1()的调用将返回已解析的结果或被Promise拒绝的结果Promise。然后,您可以使用guest271314建议的解决方案:

Promise
.all([loader1(), loader2(), loader3()])
.then(function(result) {
  // var result1 = result[0];
  // var result2 = result[1];
  // var result3 = result[1];
 })
 .catch(function (err) {
   // problem
 });
Run Code Online (Sandbox Code Playgroud)

但是请注意,a是同步Promise执行的。这意味着它不会自动等待内的任何异步操作完成。您只有在异步操作完成后才解决它(通常通过解析传递给异步函数的回调)来自己解决。Promise