【问题标题】:Creating a promise callback创建一个承诺回调
【发布时间】:2016-03-13 14:43:48
【问题描述】:

所以我很难弄清楚如何创建一个适用于不同 firebase 查询/不同承诺的函数。

考虑一下这个promise,它将一个空的输出数组转换为查询/promise的返回数据。

//userKeys is an array with my 'queries' 
Promise.all(userKeys.map(function(key) {
        return database.child(key).once("value") //Returns a promise
    })).then(function(respond) {
        userData = respond;
    });

这非常有效。所以我想我会创建一个函数来处理不同的查询,这就是我刚刚走到死胡同的地方。

所以我将我之前的代码包装在一个函数中

function query(keys, array) {
    return Promise.all(keys.map(function(key) {
        return ref.child(key).once("value")
    })).then(function(respond) {
        array = respond; //This won't work
        return respond;
    });
}

所以我尝试返回承诺,然后我可以这样做

someQuery = query(queryKeys);
someQuery.then(function(data){ //Manual written array to store data here
queryResults = data})

我仍然需要以编程方式将这些数据存储在一个数组中,我只是想不通。

所以回头看看我上面的第二个 sn-p 代码(我的函数)第二个参数是我要传递的数组,我选择的数组将填充数据,但赢了也不行。如果我进一步简化我的功能,我就会开始看到奇怪的东西。

output = [];
function modify(arrayName) {
    var data = ["1", "2", "3", "4"];
    arrayName = data;  //Doesnt work
    arrayName = data.slice() //Doesnt work
    arrayName.push(data) //Works, but I don't want to push I want to copy
}
modify(output); //Output will stay empty

为什么我的输出数组保持为空?这是正常的吗?此外,当我控制台日志 arrayName 它返回一个对象时,它显然是一个数组。有人可以详细说明吗?

我有一种感觉,我最终将不得不为我将来要进行的每个查询手动编写一个承诺,我只是想知道是否有更有效的方法来做到这一点。

【问题讨论】:

    标签: javascript firebase promise


    【解决方案1】:

    在 JavaScript 中,任何非原始值都通过“引用副本”(more details in this answer) 传递。

    您可以使用Array#splice() 更新给定数组的内容,例如:

    function mutate(arr) { arr.splice(0, arr.length, 1, 2, 3); }
    var a = [];
    mutate(a);
    console.log(a); // [1,2,3]
    

    splice 函数对您的情况有点不方便,因为它希望每个新项目都作为单独的参数传递。这可以通过使用Function#apply()(或现代JS中的spread operator)来解决:

    function mutate(dest, src) { dest.splice.apply(dest, [0, dest.length].concat(src)); }
    var arr = [1,2,3];
    mutate(arr, [6]);
    console.log(arr); // [ 6 ]
    

    更简单的方法是将包含数组的对象传递给您的 mutator 函数:

    var myData = { array: [] };
    function mutate(obj, newArray) {
      obj.array = newArray;
    }
    mutate(myData, [1,2,3]);
    

    也就是说,您确定不需要承诺提供的回调吗?如果您使用您描述的辅助函数,您将不会收到有关何时/是否收到数据的任何反馈。换句话说,“所以我尝试返回我可以执行此操作的承诺”步骤有什么问题?

    【讨论】:

    • 但是请,请不要。这真的不是承诺的使用方式。
    • @MadaraUchiha 您指的是答案的第一部分,带有拼接和应用吗?
    • @MadaraUchiha 最终一旦加载数据,它将使用 angularJS 在视图中呈现。那么尼科莱做错了什么?而Nickolay,它的问题在于,我必须分别为每一个承诺做这件事。我想不出以编程方式做到这一点的方法,我知道我不会得到任何反馈,但我认为我不需要它,因为无论如何我都会在它加载后立即在我的视图中呈现它。跨度>
    • @5parc:我认为关于如何在 Angular 中执行此操作的另一个问题可以帮助您产生更好的解决方案。听起来您尝试编写的通用承诺不应仅将结果存储在单独的 JS 对象中,还应让 angularJS 更新视图。如果你走那条路,我有理由确定你不需要我在这里发布的 sn-ps。
    • @Nickolay 我的意思是使用 Promise 来改变一些更高范围的变量,希望将来某个时候其他脚本可以读取它。
    猜你喜欢
    • 2020-12-05
    • 2016-05-15
    • 2015-11-27
    • 1970-01-01
    • 2016-06-15
    • 2013-05-20
    • 2015-06-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多