1

Habe mich umgesehen und kann die Antwort nicht ganz finden. Ich versuche, ein Versprechen zu führen, das eine Erfüllungserklärung ausführt, sobald alle facebook api-Seiten durchlaufen und in einem Array gespeichert worden sind.Warum läuft mein Versprechen nicht synchron?

Ich weiß, dass die Funktion hässlich ist, aber ich versuche herauszufinden, wie weit ich mit Versprechungen kommen kann.

function pageThroughLikes(facebookPostArray) { 
    var testArray = [] 
    return new Promise(function (fulfill, reject) { 
    facebookPostArray.forEach(function(array) { 
     array.forEach(function(innerObject) { 
     if ('likes' in innerObject) { 
      if ('paging' in innerObject.likes) { 
      if ('next' in innerObject.likes.paging) { 
       nextPage = innerObject.likes.paging.next; 
       currentPostId = innerObject.id; 
       currentDataLength = innerObject.likes.data.length; 
       i = 0; 
       do{ 
       $.get(nextPage, function(nextLikePageData) { 
        likeData = {}; 
        likeData.id = currentPostId; 
        likeData.likes = {}; 
        likeData.likes.data = nextLikePageData.data 
        likeData.likes.paging = nextLikePageData.paging 
        console.log(likeData) 
        testArray.push(likeData); 
        facebookPostArray.push(testArray); 
        console.log('pushed to postArray') 
       }) 
       i += 1; 
       } while (currentDataLength != 0 && i > 10) 
       } 
      } 
     } 
     }) 
    }); 
    fulfill(); 
    console.log('paged through likes') 
}) 
} 

Im Moment einmal diese Funktion abgeschlossen Ich mag eine ‚Test‘ Funktion ausführen, die in CSV-Format meine resultierende Array konvertiert und lädt eine CSV-Datei.

Hier ist meine Testfunktion:

function test() { 
    var convertedPostCSV = convertArrayOfObjectsToCSV(postArray); 
    downloadCSV(convertedPostCSV); 
} 

Und hier ist mein laufender Auftrag für Funktionen:

$(document).ready(function() { 
    getPostLikes().then(function() { 
    pageThroughLikes(postArray).then(function() { 
     test(); 
    }); 
    }); 
}); 

Was mit ich bin zu kämpfen, ist, dass mein ‚test()‘ Funktion, bevor der ausgeführt werden Daten von neuen Seiten mit Likes werden zu meinem "facebookPostArray" hinzugefügt oder bevor die pageThroughLikes-Funktion endet.

Ich hoffe, jemand kann mir einen Rat geben/in die richtige Richtung weisen.

EDIT

Ok, ich habe meinen Code als @Winter Soldat hat vorgeschlagen, neu formatiert, aber ich bin immer noch ein nicht erfasster Fehler für die processData Funktion bekommen.

Hier ist mein Code:

function pageThroughLikes(facebookPostArray) { 
console.log('paging through likes') 
var testArray = [] 
var promiseList = []; 
return new Promise(function (fulfill, reject) { 
    facebookPostArray.forEach(function(array) { 
     array.forEach(function(innerObject) { 
     if ('likes' in innerObject) { 
      if ('paging' in innerObject.likes) { 
      if ('next' in innerObject.likes.paging) { 
       nextPage = innerObject.likes.paging.next; 
       currentPostId = innerObject.id; 
       currentDataLength = innerObject.likes.data.length; 
       i = 0; 
       do{ 
        promiseList.push(
        $.ajax({url : nextPage 
         })) 
         i += 1; 
        } while (currentDataLength != 0 && i > 10) 
       } 
      } 
     } 
    }); 
    return promiseList; 
    console.log('paged through likes') 
}) 

processData = function(nextLikePageData){ 
    likeData = {}; 
        likeData.id = currentPostId; 
        likeData.likes = {}; 
        likeData.likes.data = nextLikePageData.data 
        likeData.likes.paging = nextLikePageData.paging 
        console.log(likeData) 
        testArray.push(likeData); 
        facebookPostArray.push(testArray); 
        console.log('pushed to postArray') 
    return likeData; 
} 

$(document).ready(function() { 
    getPostLikes().then(function() { 
    $.when.apply(pageThroughLikes(postArray), this).done(function() { 

    var testArray = [] 
    $.each(arguments, function(k, v){ 
     var dt = processData(v[0]); 
     testArray.push(dt); 
     facebookPostArray.push(dt); 
    }); 
    console.log(testArray) 
    test(testArray); // OR 
    test(facebookPostArray); 
    }); 
}); 
}); 

function test(postArray) { 
    var convertedPostCSV = convertArrayOfObjectsToCSV(postArray); 
    downloadCSV(convertedPostCSV); 
} 

EDIT 2,0

Hier ist mein vollständiger Code in seiner ganzen Hässlichkeit. Nur als Referenz. Abbildung das Problem mit etwas könnte ich verstecken irgendwo in dem Rest meines Code weg so möglicherweise wert Sie in vollem Umfang zeigen ...

var facebookKey = config.FACEBOOK_KEY; 

// ASSIGN QUERY TO VARIABLE 

var likePage = getQueryVariable("likePage"); 
var sinceDate = getQueryVariable("sinceDate"); 
var likeArray = []; 
var postArray = []; 


function getQueryVariable(variable) { 
    var query = window.location.search.substring(1); 
    var vars = query.split('&'); 
    for (var i = 0; i < vars.length; i++) { 
    var pair = vars[i].split('='); 
    if (pair[0] == variable) { 
     return pair[1]; 
    } 
    } 
    alert("Query Variable " + variable + " not found"); 
} 

console.log("Page Search: " + likePage); 
console.log("Since: " + sinceDate) 

// FIND DATA FOR FACEBOOK PAGE POSTS SINCE CHOSEN DATE 

$(document).ready(function() { 
    getPostLikes().then(function() { 
    $.when.apply(pageThroughLikes(postArray), this).done(function() { 
    var testArray = [] 
    $.each(arguments, function(k, v){ 
     var dt = processData(v[0]); 
     testArray.push(dt); 
     facebookPostArray.push(dt); 
    }); 
    console.log(testArray) 
    test(testArray); // OR 
    test(facebookPostArray); 
    }); 
}); 
}); 

function test(postArray) { 
    var convertedPostCSV = convertArrayOfObjectsToCSV(postArray); 
    downloadCSV(convertedPostCSV); 
} 

function getPostLikes(response) { 
    return new Promise(function (fulfill, reject) { 
    $.get("https://graph.facebook.com/v2.8/"+ likePage + "?fields=access_token,posts.since(" + sinceDate + "){likes{id}}&access_token=" + facebookKey, function (facebookData) { 

     var likePageId = facebookData.id; 
     var testPostArray = []; 
     if ('posts' in facebookData) { 
     var nextPage = facebookData.posts.paging.next; 
     var check = 0; 

     postArray.push(facebookData.posts.data); 

     var currentDataLength = " " 
     var i = 0 
     if ('paging' in facebookData.posts) { 
      console.log("new page available"); 
      do { 
      $.ajax({ 
       async: false, 
       type: "GET", 
       url: nextPage, 
       success: function(nextPageData) { 
       console.log("New Page Accessed: " + nextPage) 
       i++; 
       console.log("Page Number: " + i) 
       testPostArray.push(nextPageData.data); 
       if ('paging' in nextPageData) { 
        nextPage = nextPageData.paging.next; 
        console.log("next page assigned"); 
       } 
       currentDataLength = nextPageData.data.length; 
       console.log(currentDataLength); 
       } 
      }); 
      console.log("DATA LENGTH: " + currentDataLength); 
      } while (currentDataLength > 0); 
      testPostArray.forEach(function(element) { 
      console.log(element) 
      postArray.push(element); 
      fulfill(); 
      }); 
     } 
     } else { 
     console.log('Error: No facebook posts since this date!') 
     reject(); 
     } 
     console.log(postArray) 
    }); 
    }) 
}; 
console.log("Downloading...") 


function pageThroughLikes(facebookPostArray) { 
console.log('paging through likes') 
var testArray = [] 
var promiseList = []; 
    facebookPostArray.forEach(function(array) { 
     array.forEach(function(innerObject) { 
     if ('likes' in innerObject) { 
      if ('paging' in innerObject.likes) { 
      if ('next' in innerObject.likes.paging) { 
       nextPage = innerObject.likes.paging.next; 
       currentPostId = innerObject.id; 
       currentDataLength = innerObject.likes.data.length; 
       i = 0; 
       do{ 
        promiseList.push(
        $.ajax({url : nextPage 
         })) 
         i += 1; 
        } while (currentDataLength != 0 && i > 10) 
       } 
      } 
      } 
     }) 
    }); 
    console.log('paged through likes') 
    return promiseList; 
} 

processData = function(nextLikePageData){ 
    likeData = {}; 
        likeData.id = currentPostId; 
        likeData.likes = {}; 
        likeData.likes.data = nextLikePageData.data 
        likeData.likes.paging = nextLikePageData.paging 
        console.log(likeData) 
        testArray.push(likeData); 
        facebookPostArray.push(testArray); 
        console.log('pushed to postArray') 
    return likeData; 
} 


    // AUTO DOWNLOAD CSV FILE 

    function downloadCSV(args) { 
    var data, filename, link; 
    var csv = convertArrayOfObjectsToCSV(postArray); 

    if (csv == null) return; 

    filename = args.filename || 'export.csv'; 

    if (!csv.match(/^data:text\/csv/i)) { 
     csv = 'data:text/csv;charset=utf-8,' + csv; 
    } 
    data = encodeURI(csv); 

    link = document.createElement('a'); 
    link.setAttribute('href', data); 
    link.setAttribute('download', filename); 
    link.click(); 
    } 
    // CONVERT FACEBOOK POSTS OBJECTS TO CSV FORMAT 

    function convertArrayOfObjectsToCSV(args) { 
    var result, ctr, keys, columnDelimiter, lineDelimiter, data; 

    data = args || null; 
    if (data == null || !data.length) { 
     return null; 
    } 

    columnDelimiter = args.columnDelimiter || ','; 
    lineDelimiter = args.lineDelimiter || '\n'; 

    keys = Object.keys(data[0]); 

    result = ''; 
    result += "user_id" + columnDelimiter + " post_id" + columnDelimiter + " page_id"; 
    result += lineDelimiter; 

    data.forEach(function(item) { 
     item.forEach(function(post) { 
     if ('likes' in post) { 
      var likeArray = post.likes 
      likeArray.data.forEach(function(like) { 
      result += like.id + columnDelimiter + post.id.split('_').reverse() + lineDelimiter; 
      }); 
     } else { 
      result += columnDelimiter + post.id.split('_').reverse() + lineDelimiter; 
     }; 
     }); 
    }); 
    console.log('converted to CSV') 
    return result; 
    } 

EDIT 3.0

Funktion ist fast fixiert, nur Ausgabe ist, dass es nicht looping ist. Läuft perfekt einmal!

function pageThroughLikes(facebookPostArray) { 
console.log('paging through likes') 
var testArray = [] 
var promiseList = []; 
// return new Promise(function (fulfill, reject) { 
    facebookPostArray.forEach(function(array) { 
     array.forEach(function(innerObject) { 
     if ('likes' in innerObject) { 
      if ('paging' in innerObject.likes) { 
      if ('next' in innerObject.likes.paging) { 
       nextPage = innerObject.likes.paging.next; 
       currentPostId = innerObject.id; 
       currentDataLength = innerObject.likes.data.length; 
       i = 0; 
       do{ 
        promiseList.push(
        $.ajax({url : nextPage 
         }).then(function(data, b, promise){ 
         data.id = currentPostId; 
         if ('paging' in data) { 
         if ('next' in data.paging) { 
          nextPage = data.paging.next; 
         } 
         } 
         console.log(nextPage) 
         return promise; 
         })) 
         i += 1; 
         console.log(i) 
        } while (currentDataLength != 0 && i > 10) 
       } 
      } 
      } 
     }) 
    }); 
    console.log('paged through likes') 
    return promiseList; 
} 

bearbeiten 4.0

Hier ist meine aktuellen Code ...

Fast endlich alles funktioniert, ein paar Informationen von Lasten von Spät- googeln bekommen verwaltet.

var facebookKey = config.FACEBOOK_KEY; 

// ASSIGN QUERY TO VARIABLE 
var likePage = getQueryVariable("likePage"); 
var sinceDate = getQueryVariable("sinceDate"); 
var likeArray = []; 
var postArray = []; 

function getQueryVariable(variable) { 
    var query = window.location.search.substring(1); 
    var vars = query.split('&'); 
    for (var i = 0; i < vars.length; i++) { 
    var pair = vars[i].split('='); 
    if (pair[0] == variable) { 
     return pair[1]; 
    } 
    } 
    alert("Query Variable " + variable + " not found"); 
} 
console.log("Page Search: " + likePage); 
console.log("Since: " + sinceDate) 

// FIND DATA FOR DOJOAPP FACEBOOK PAGE POSTS SINCE CHOSEN DATE 

$(document).ready(function() { 
    getPostLikes().then(function() { 
    // console.log(postArray); 
    pageThroughLikes(postArray, test) 
}); 
}); 

function test(postArray) { 
    var convertedPostCSV = convertArrayOfObjectsToCSV(postArray); 
    downloadCSV(convertedPostCSV); 
} 

function getPostLikes(response) { 
    return new Promise(function (fulfill, reject) { 
    $.get("https://graph.facebook.com/v2.8/"+ likePage + "?fields=access_token,posts.since(" + sinceDate + "){likes{id}}&access_token=" + facebookKey, function (facebookData) { 
     var likePageId = facebookData.id; 
     var testPostArray = []; 
     if ('posts' in facebookData) { 
     var nextPage = facebookData.posts.paging.next; 
     var check = 0; 
     postArray.push(facebookData.posts.data); 
     var currentDataLength = " " 
     var i = 0 
     if ('paging' in facebookData.posts) { 
      console.log("new page available"); 
      do { 
      $.ajax({ 
       async: false, 
       type: "GET", 
       url: nextPage, 
       success: function(nextPageData) { 
       console.log("New Post Page Accessed: " + nextPage) 
       i++; 
       console.log("Paging Through Posts: " + i) 
       testPostArray.push(nextPageData.data); 
       if ('paging' in nextPageData) { 
        nextPage = nextPageData.paging.next; 
        console.log("next page assigned: " + nextPage); 
       } 
       currentDataLength = nextPageData.data.length; 
       console.log(currentDataLength); 
       } 
      }); 
      console.log("DATA LENGTH: " + currentDataLength); 
      } while (currentDataLength > 0); 
      testPostArray.forEach(function(element) { 
      // console.log(element) 
      postArray.push(element); 
      fulfill(); 
      }); 
     } 
     } else { 
     console.log('Error: No facebook posts since this date!') 
     reject(); 
     } 
     // console.log(postArray) 
    }); 
    }) 
}; 
console.log("Downloading...") 


function pageThroughLikes(facebookPostArray, callback) { 
console.log('paging through likes') 
var testArray = [] 
var promiseList = []; 
    facebookPostArray.forEach(function(array) { 
    array.forEach(function(innerObject) { 
     if ('likes' in innerObject && 'paging' in innerObject.likes && 'next' in innerObject.likes.paging) { 
     var nextPage = innerObject.likes.paging.next; 
     console.log('new likes page assigned: ' + nextPage); 
     var currentPostId = innerObject.id; 
     var noMorePages = false; 
     var i = 0; 
     do{ 
     $.ajax({ 
      url: nextPage, 
      success: function(nextLikePageData) { 
      createLikeObject(nextLikePageData, currentPostId, checkForPagesOfLikes, nextLikePageData, noMorePages) 
      if ('paging' in nextLikePageData && 'next' in nextLikePageData.paging) { 
       nextPage = nextLikePageData.paging.next; 
      } 
      } 
      }) 
     i += 1 
     console.log(i) 
     } while (noMorePages = false); 
     } 
    }) 
    }); 
    console.log('paged through likes') 
    callback(); 
} 

function createLikeObject(likeData, postId, callback, args, fail) { 
    likeArrayFormat = []; 
    likeObject = {}; 
    likeObject.likes = {}; 
    likeObject.id = postId; 
    likeObject.likes.data = [] 
    likeData.data.forEach(function(like) { 
    likeObject.likes.data.push(like); 
    }); 
    likeArrayFormat.push(likeObject); 
    postArray.push(likeArrayFormat); 
    console.log('pushed new like data to postArray') 
    callback(args, fail) 
} 

function pushToArray(item, array, callback) { 
    array.push(item); 
    callback() 
} 

function checkForPagesOfLikes(data, noMorePages) { 
    if ('paging' in data && 'next' in data.paging) { 
     return true; 
     console.log('NEW PAGE FOUND') 
    } 
    else { 
    noMorePages = true; 
    console.log('NO MORE PAGES OF LIKES FOR CURRENT OBJECT') 
    } 
} 

    // AUTO DOWNLOAD CSV FILE 
    function downloadCSV(args) { 
    var data, filename, link; 
    var csv = convertArrayOfObjectsToCSV(postArray); 
    if (csv == null) return; 
    filename = 'export.csv'; 
    if (!csv.match(/^data:text\/csv/i)) { 
     csv = 'data:text/csv;charset=utf-8,' + csv; 
    } 
    data = encodeURI(csv); 
    link = document.createElement('a'); 
    link.setAttribute('href', data); 
    link.setAttribute('download', filename); 
    link.click(); 
    } 

    // CONVERT FACEBOOK POSTS OBJECTS TO CSV FORMAT 

    function convertArrayOfObjectsToCSV(args, callback) { 
    var result, ctr, keys, columnDelimiter, lineDelimiter, data; 
    // console.log(args) 
    data = args || null; 
    if (data == null || !data.length) { 
     return null; 
    } 
    columnDelimiter = args.columnDelimiter || ','; 
    lineDelimiter = args.lineDelimiter || '\n'; 
    keys = Object.keys(data[0]); 
    result = ''; 
    result += "user_id" + columnDelimiter + " post_id" + columnDelimiter + " page_id"; 
    result += lineDelimiter; 
    // console.log(args) 
    args.forEach(function(object) { 
     // console.log(object) 
     // console.log(object.length) 
     if (object.length != 0) { 
     object.forEach(function(item) { 
      if ('likes' in item && 'data' in item.likes) { 
      var postId = item.id; 
      item.likes.data.forEach(function(likeId) { 
       if ('id' in likeId) { 
       // console.log(likeId) 
       var likeArray = likeId; 
       // console.log(likeArray) 
        result += likeArray.id + columnDelimiter + postId.split('_').reverse() + lineDelimiter; 
       } else { 
       result += columnDelimiter + postId.split('_').reverse() + lineDelimiter; 
       }; 
      }); 
      } 
     }); 
     } 
    }) 
    console.log('converted to CSV') 
    return result; 
    callback(); 
    } 

Big Problem ist im Moment, dass convertArrayObObjectsToCSV ausgeführt wird, bevor die createLikeObject Funktion abgeschlossen ist. Gedankenrückrufe hätten funktioniert, aber es scheint, dass ich etwas nicht richtig verstanden habe.

+0

jedes solche '$ .get() 'Anrufe starten einen weiteren asynchronen Vorgang. Ihr Code ruft 'fulfill()' auf, bevor diese beendet werden. – Pointy

+0

Müssen Sie fulfull() anrufen. Kannst du es ohne es versuchen? –

+0

@WinterSoldier, versuchen, Versprechen, wo möglich, in den Griff zu bekommen, also möchte ich sie verwenden, um dies zu lösen (es sei denn, es ist natürlich völlig unnötig!). – LastMan0nEarth

Antwort

-2

Sie müssen den Wert, den Sie benötigen, aus Versprechen erfüllen/auflösen. Rufen Sie die Funktion fulfile mit einem Wert an, den Sie brauchen.Wenn Sie zum Beispiel möchten, um ein Array zu beheben:

fullfill(array); 
+0

Würden Sie dazu in der Lage sein? Wenn ich das facebookPostArray-Argument zu meiner Erfüllungsfunktion hinzufüge, bekomme ich das gleiche Ergebnis. Oder meinst du, ich muss eine Variable zuweisen, wenn meine $ .get() - Funktion endet und diese in meine Erfüllung übergeben? – LastMan0nEarth

0

Hier könnte sein, einen Weg, es zu tun, da Sie bekommen Anruf verwenden, habe ich geändert, um nicht versprechen zu verwenden überhaupt, weil Ajax das Versprechen ohnehin zurückgibt.

Es ist ein Pseudo-Code, könnten Sie haben es ein wenig zwicken, um es

function pageThroughLikes(facebookPostArray) { 
    var testArray = [] 
    var promsieList = [] 
    facebookPostArray.forEach(function(array) { 
     array.forEach(function(innerObject) { 
     if ('likes' in innerObject) { 
      if ('paging' in innerObject.likes) { 
      if ('next' in innerObject.likes.paging) { 
       nextPage = innerObject.likes.paging.next; 
       currentPostId = innerObject.id; 
       currentDataLength = innerObject.likes.data.length; 
       i = 0; 
       do{ 
       promsieList.push(
       $.ajax({url : nextPage     
       })) 
       i += 1; 
       } while (currentDataLength != 0 && i > 10) 
       } 
      } 
     } 
     }) 
    }); 
    console.log('paged through likes') 
    return promiseList();  
} 

processData = function(nextLikePageData){ 
    likeData = {}; 
        likeData.id = currentPostId; 
        likeData.likes = {}; 
        likeData.likes.data = nextLikePageData.data 
        likeData.likes.paging = nextLikePageData.paging 
        console.log(likeData) 
        testArray.push(likeData); 
        facebookPostArray.push(testArray); 
        console.log('pushed to postArray') 
    return likeData; 
} 

$(document).ready(function() { 
    getPostLikes().then(function() { 
    $.when.apply(this, pageThroughLikes(postArray)).done(function() { 
    //debug to examine the arguments object, you'll notice its an array of arrays 
    var testArray = [] 
    $.each(arguments, function(k, v){ 
     var dt = processData(v[0]); 
     testArray.push(dt); 
     facebookPostArray.push(dt);   
    }); 
    console.log(testArray) 
    test(testArray); // OR 
    test(facebookPostArray); 
    }); 
}); 
}); 

function test(postArray) { 
    var convertedPostCSV = convertArrayOfObjectsToCSV(postArray); 
    downloadCSV(convertedPostCSV); 
} 

EDIT zum Laufen bringen:

  • Die Argumente Objekt ist eine Standardinstallation durch die jquery $ .when zurück Funktion.
  • Dies ist eine Sammlung von Subarrays und jedes Subarray besteht aus Daten, Status & Versprechen Objekt.
  • Ich gehe davon aus, dass Sie die Daten von allen bekommen Anrufe in einer testarray so konsolidieren müssen, ist das, was in dem Ruf, wenn getan wird
+0

In der '$ (document) .ready 'Funktion, welche Argumente sollte ich verwenden, um die Daten aufzulösen? Dies ist der Teil, den ich nicht verstehe. Versuchen Sie, alle in 'pageThroughLikes' gesammelten Daten vor dem Test an das Array 'processedData' zu senden? Und wenn ja, warum muss das getan werden? – LastMan0nEarth

+0

Interessant. Ist processData etwas eingebaut zu $ ​​.when? Einen Referenzfehler erhalten, da dieser nicht definiert ist. – LastMan0nEarth

+0

Beantwortete Ihre Fragen in der Post. Auch ich verstehe nicht, warum Sie durch das gleiche Array von facebookPostArray iterieren, um die Parameter zu zeichnen, um Anruf zu erhalten und das gleiche Array zu verwenden, um die Ergebnisse zu pushen? –

Verwandte Themen