Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 可以保证按顺序加载多个URL吗?_Javascript_Promise - Fatal编程技术网

Javascript 可以保证按顺序加载多个URL吗?

Javascript 可以保证按顺序加载多个URL吗?,javascript,promise,Javascript,Promise,给出以下代码段: function get(url) { return new Promise(function(resolve, reject) { var req = new XMLHttpRequest(); req.open('GET', url); req.onload = function() { if (req.status == 200) { resolve(req.response); } els

给出以下代码段:

function get(url) {
  return new Promise(function(resolve, reject) {
    var req = new XMLHttpRequest();
    req.open('GET', url);

    req.onload = function() {
      if (req.status == 200) {
        resolve(req.response);
      }
      else {
        reject(Error(req.statusText));
      }
    };
    req.onerror = function() {
      reject(Error("Network Error"));
    };
    req.send();
  });
}
此功能可按如下方式使用:

get('story.json').then(function(response) {
  console.log("Success!", response);
}, function(error) {
  console.error("Failed!", error);
});
我想使用promise加载多个URL,例如

get('a.json').get('b.json')
// or get('a.json').then().get('b.json')
我已经用其他方式实现了它。但据我所知,允诺不能做这项工作。真的吗

添加 事实上,我实现了一个类似的库来帮助在浏览器中执行动态脚本:

Loader = (function() {

  var load_cursor = 0;
  var load_queue;

  var loadFinished = function() {
    load_cursor ++;
    if (load_cursor < load_queue.length) {
      loadScript();
    }
  }

  function loadError (oError) {
    console.error("The script " + oError.target.src + " is not accessible.");
  }


  var loadScript = function() {
    var url = load_queue[load_cursor];
    var script = document.createElement('script');
    script.type = "text/javascript";

    if (script.readyState){  //IE
        script.onreadystatechange = function(){
            if (script.readyState == "loaded" ||
                    script.readyState == "complete"){
                script.onreadystatechange = null;
                loadFinished();
            }
        };
    } else {  //Others
        script.onload = function(){
            loadFinished();
        };
    }

    script.onerror = loadError;

    script.src = url+'?'+'time='+Date.parse(new Date());
    document.body.appendChild(script);
  };

  var loadMultiScript = function(url_array) {
    load_cursor = 0;
    load_queue = url_array;
    loadScript();
  }

  return {
    load: loadMultiScript,
  };

})();  // end Loader


// load...

Loader.load(['http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js', './my.js']);
Loader=(函数(){
var load_cursor=0;
var负载队列;
var loadFinished=函数(){
加载光标++;
if(加载游标<加载队列长度){
loadScript();
}
}
函数加载错误(oError){
错误(“脚本“+oError.target.src+”不可访问。”);
}
var loadScript=函数(){
var url=load_队列[load_游标];
var script=document.createElement('script');
script.type=“text/javascript”;
if(script.readyState){//IE
script.onreadystatechange=函数(){
如果(script.readyState==“已加载”||
script.readyState==“完成”){
script.onreadystatechange=null;
loadFinished();
}
};
}其他{//其他
script.onload=函数(){
loadFinished();
};
}
script.onerror=loadError;
script.src=url+'?'+'time='+Date.parse(new Date());
document.body.appendChild(脚本);
};
var loadMultiScript=函数(url\u数组){
加载光标=0;
load_queue=url_数组;
loadScript();
}
返回{
load:loadMultiScript,
};
})();  // 端部装载机
//加载。。。
Loader.load(['http://cdnjs.cloudflare.com/ajax/libs/jquery/2.0.0/jquery.min.js“,”./my.js']);

您可以加入承诺,在这种情况下,您必须从成功回调返回下一个承诺

get('story.json').then(function(response) {
     console.log("Success!", response);
    return get('b.json');
   }, function(error) {
   console.error("Failed!", error);
}).then(function(res){
 // response for b
});
使用普通承诺语法 连锁承诺

如果你想让你的承诺循序渐进,你可以将它们连成链条:

get('a.json').then(function(a) {
    return get('b.json');
}).then(function(b){
    return get('c.json');
}).then(function(c) {
    // all done here
}), function(err) {
    // error here
});
或者在ES7中,您可以像这样使用
async/await

async function someFunction() {
    let a = await get('a.json');
    let b = await get('b.json');
    // do something with a and b here
    return something;
}

someFunction().then(result => {
    // all done here
}).catch(err => {
    // error here
});
并行运行承诺

如果希望并行加载,可以使用
Promise.all()

使用.reduce()排序

或者,如果使用相同的代码处理每个结果,则可以使用
reduce()
设计模式按顺序加载它们:

['a.json', 'b.json', 'c.json'].reduce(function(p, item) {
    return p.then(function(){
        // process item here
    });
}, Promise.resolve()).then(function(result) {
    // all done here
}, function(err) {
    // error here
});
使用Bluebird的.map()进行排序

或者,如果使用Bluebird promise库,它有
promise.map()
,这对于阵列上的并行操作非常有用

Promise.map(['a.json', 'b.json', 'c.json'], function(item) {
    // do some operation on item and return data or a promise
    return something;
}).then(function(results) {
    // all done
}, function(err) {
    // error here
});

使
get(x).get(y).get(z)
工作 扩展承诺

我对使用承诺的
get(x).get(y).get(z)
问题很感兴趣。在这个工作片段中,我想出了一个方法:

函数get(url){
函数pget(u){
var p=这个。然后(函数(结果){
日志(结果);
返回get(u);
});
p、 get=pget;
返回p;
}
var p=新承诺(功能(解决、拒绝){
setTimeout(函数(){
解析(url);
}, 500);
});
p、 get=pget;
返回p;
}
get('a.json')。get('b.json')。get('c.json')。然后(函数(结果){
日志(结果);
日志(“完成”);
},函数(err){
日志(“err”);
});
函数日志(x){
var div=document.createElement(“div”);
div.innerHTML=x;
文件.正文.附件(div);

}
你很接近了。您需要学习如何正确使用
,然后才能设置
。get
不是一种承诺的方法,它只是一个正常的功能。听起来你想要
Promise.all([get('a'),get('b')]),然后(function([aresult,bresult]){…})loadMultiScript
只需附加到
loadu queue
,将
loadu cursor
重置为
0
并开始第一个
loadScript()
(让
loadFinished
完成剩下的工作),而不是在一个循环中多次调用
loadScript()
?这将并行加载每个,而不是按顺序加载。我想你应该阅读文章中的一章,你的linkedIt将导致“回调地狱”这不是回叫地狱,回叫地狱是做成功回叫里面的每一件事简洁的回答。谢谢much@defau1t-我又增加了两个选项。@jjfriend00不幸的是,我不能进行双重投票。但是谢谢though@defau1t-我添加了一种执行
get(x).get(y).get(z)
的方法。
Promise.map(['a.json', 'b.json', 'c.json'], function(item) {
    // do some operation on item and return data or a promise
    return something;
}).then(function(results) {
    // all done
}, function(err) {
    // error here
});