javascript – 如何将Promise.all与对象一起用作输入
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了javascript – 如何将Promise.all与对象一起用作输入,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3237字,纯文字阅读大概需要5分钟。
内容图文
![javascript – 如何将Promise.all与对象一起用作输入](/upload/InfoBanner/zyjiaocheng/712/109bedcc47bd4ce6ab01688959bbaee4.jpg)
我一直在为我自己使用的小型2D游戏库工作,我遇到了一些问题.库中有一个名为loadGame的特定函数,它将依赖信息作为??输入(资源文件和要执行的脚本列表).这是一个例子.
loadGame({
"root" : "/source/folder/for/game/",
"resources" : {
"soundEffect" : "audio/sound.mp3",
"someImage" : "images/something.png",
"someJSON" : "json/map.json"
},
"scripts" : [
"js/helperScript.js",
"js/mainScript.js"
]
})
资源中的每个项目都有一个密钥,游戏使用该密钥来访问该特定资源. loadGame函数将资源转换为promises对象.
问题是它试图使用Promises.all来检查它们何时准备就绪,但是Promise.all只接受迭代作为输入 – 所以像我所拥有的对象是不可能的.
所以我尝试将对象转换为数组,这很有效,除了每个资源只是数组中的一个元素,并且没有用于标识它们的键.
这是loadGame的代码:
var loadGame = function (game) {
return new Promise(function (fulfill, reject) {
// the root folder for the game
var root = game.root || '';
// these are the types of files that can be loaded
// getImage, getAudio, and getJSON are defined elsewhere in my code - they return promises
var types = {
jpg : getImage,
png : getImage,
bmp : getImage,
mp3 : getAudio,
ogg : getAudio,
wav : getAudio,
json : getJSON
};
// the object of promises is created using a mapObject function I made
var resources = mapObject(game.resources, function (path) {
// get file extension for the item
var extension = path.match(/(?:\.([^.]+))?$/)[1];
// find the correct 'getter' from types
var get = types[extension];
// get it if that particular getter exists, otherwise, fail
return get ? get(root + path) :
reject(Error('Unknown resource type "' + extension + '".'));
});
// load scripts when they're done
// this is the problem here
// my 'values' function converts the object into an array
// but now they are nameless and can't be properly accessed anymore
Promise.all(values(resources)).then(function (resources) {
// sequentially load scripts
// maybe someday I'll use a generator for this
var load = function (i) {
// load script
getScript(root + game.scripts[i]).then(function () {
// load the next script if there is one
i++;
if (i < game.scripts.length) {
load(i);
} else {
// all done, fulfill the promise that loadGame returned
// this is giving an array back, but it should be returning an object full of resources
fulfill(resources);
}
});
};
// load the first script
load(0);
});
});
};
理想情况下,我想以某种方式正确管理资源的承诺列表,同时仍然保留每个项目的标识符.任何帮助将不胜感激,谢谢.
解决方法:
首先:废弃Promise构造函数,this usage is an antipattern!
现在,针对您的实际问题:正确识别后,您错过了每个值的关键字.您需要在每个promise中传递它,以便在等待所有项目后重建对象:
function mapObjectToArray(obj, cb) {
var res = [];
for (var key in obj)
res.push(cb(obj[key], key));
return res;
}
return Promise.all(mapObjectToArray(input, function(arg, key) {
return getPromiseFor(arg, key).then(function(value) {
return {key: key, value: value};
});
}).then(function(arr) {
var obj = {};
for (var i=0; i<arr.length; i++)
obj[arr[i].key] = arr[i].value;
return obj;
});
像Bluebird这样的更强大的库也会将其作为辅助函数提供,如Promise.props.
此外,您不应该使用该伪递归加载函数.您可以简单地将承诺链接在一起:
….then(function (resources) {
return game.scripts.reduce(function(queue, script) {
return queue.then(function() {
return getScript(root + script);
});
}, Promise.resolve()).then(function() {
return resources;
});
});
内容总结
以上是互联网集市为您收集整理的javascript – 如何将Promise.all与对象一起用作输入全部内容,希望文章能够帮你解决javascript – 如何将Promise.all与对象一起用作输入所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。