如何根据第一个

时间:2017-08-21 17:41:03

标签: javascript jquery asynchronous

在我的应用程序中,我试图从两个不同的来源收集数据。首先,它必须loop.each进入内部JSON文件并查看是否找到了数据,如果没有,则必须请求另一个$.getjson()从外部源获取数据。

所以第二个$.getjson()依赖于第一个$.getjson(),如果已经在第一个中找到了数据,有时则不需要运行。

首次$.getJSON(InternalURL, function (data) { $.each(data.Source, function (index, value) { if(artist.indexOf(value.keyword) > -1){ image = value.image; $(".bg").css("background-image", "url(" + image + ")"); } }); }); 来电:

$.getjson()

第二次$.getJSON(ExternalURL, function (data) { image = data.artist.image; (".bg").css("background-image", "url(" + image + ")"); }); 来电:

always

另一个考虑因素是这个过程的时间安排。当然,它必须尽可能快地完成,因此它在界面中不会引人注意。

更新 使用Async / Await的示例基于@Tiny Giant提供的答案 JSFiddle 目前这个代码适用于JSFiddle,但在实际应用程序中,虽然它工作正常,但它会出现一个控制台错误,因为" Uncaught(in promise)"使用诸如abortfail#!/bin/bash #RUN THIS COMMAND BEFORE FIRST USE - sudo chmod u+x locale-changer.sh #DIRECTIONS #THIS SCRIPT ASSUMES YOU HAVE ALREADY STARTED NPM RUN LOCAL OR REGION=AA DEFAULT_MARKET=PT-BR NODE_ENV=local-qat2 grunt watch #AFTER STARTING YOUR GRUNT SCRIPT OPEN A NEW TERMINAL TAB AND TYPE IN APPROPRIATE LOCALE NPM SCRIPT EXAMPLE npm run fc TO LAUNCH FRENCH CANADA LOCALE #PLEASE SEE package.json, FOR LOCALE SPECIFIC SCRIPTS. # NODEMON=nodemon # if ! [ -x "$(command -v nodemon)" ]; then # echo 'nodemon not installed using node' # NODEMON=node # fi pid=$(lsof -i tcp:3000 -t); kill -TERM $pid || kill -KILL $pid pid=$(lsof -i tcp:3001 -t); kill -TERM $pid || kill -KILL $pid pid=$(lsof -i tcp:3002 -t); kill -TERM $pid || kill -KILL $pid pid=$(lsof -i tcp:3003 -t); kill -TERM $pid || kill -KILL $pid pid=$(lsof -i tcp:3004 -t); kill -TERM $pid || kill -KILL $pid pid=$(lsof -i tcp:3005 -t); kill -TERM $pid || kill -KILL $pid pid=$(lsof -i tcp:3006 -t); kill -TERM $pid || kill -KILL $pid pid=$(lsof -i tcp:3008 -t); kill -TERM $pid || kill -KILL $pid REGION=$1 DEFAULT_MARKET=$2 NODE_ENV=$3 echo "Starting services with REGION=$REGION DEFAULT_MARKET=$DEFAULT_MARKET NODE_ENV=$NODE_ENV" current_dir=$PWD;cd /path/to/your/command/dir;special command ARGS;cd $current_dir; PORT=3003 REGION=$REGION DEFAULT_MARKET=$DEFAULT_MARKET NODE_ENV=$NODE_ENV node ../core-service1/app/server/server.js & PORT=3002 REGION=$REGION DEFAULT_MARKET=$DEFAULT_MARKET NODE_ENV=$NODE_ENV node ../code-service2/app/server/server.js & PORT=3000 REGION=$REGION DEFAULT_MARKET=$DEFAULT_MARKET NODE_ENV=$NODE_ENV nodemon ../router/app/server/server.js & PORT=3001 REGION=$REGION DEFAULT_MARKET=$DEFAULT_MARKET NODE_ENV=$NODE_ENV node ./app/server/server.js & PORT=3004 REGION=$REGION DEFAULT_MARKET=$DEFAULT_MARKET NODE_ENV=$NODE_ENV node ../core-service3/app/server/server.js & PORT=3005 REGION=$REGION DEFAULT_MARKET=$DEFAULT_MARKET NODE_ENV=$NODE_ENV node ../core-service4/app/server/server.js & PORT=3008 REGION=$REGION DEFAULT_MARKET=$DEFAULT_MARKET NODE_ENV=$NODE_ENV nodemon ../core-service5/app/server/server.js trap "trap - SIGTERM && kill -- -$$" SIGINT SIGTERM EXIT 等方法的对象。任何想法为什么会出现此错误?

2 个答案:

答案 0 :(得分:3)

您可以使用Async / Await(最初在ECMAScript® 2017 Language Specification中定义)。有关当前支持的信息,请参阅caniuse.com

这可以通过暂停当前执行上下文并在getJSON调用开始后将其从堆栈中删除来实现。一旦$.getJSON调用返回,暂停的执行上下文将被添加回堆栈,然后一旦处理了堆栈中的前面项,执行将继续。



(async () => {
    const post = await $.getJSON('https://jsonplaceholder.typicode.com/posts/1');
    const comments = await $.getJSON('https://jsonplaceholder.typicode.com/comments');
    post.comments = comments.filter(e => e.postId === post.id);
    console.log(post);
})();

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
&#13;
&#13;
&#13;

要将此应用于您的特定示例,您可以使用以下代码:

(async () => {
    let image, data = await $.getJSON(InternalURL);
    if(data) {
        for(let value of data.Source) {
            if(!image && artist.indexOf(value.keyword) > -1) {
                image = value.image;
            }
        }
    } else {
        // request failed
    }
    if(!image) {
        let data = await $.getJSON(ExternalURL);
        if(data) {
            image = data.artist.image;
        } else {
            // request failed
        }
    }
    $(".bg").css("background-image", "url(" + image + ")");
})();

这会请求第一个资源,然后 - 一旦请求完成并继续执行 - 它会像您的示例一样检查响应。如果脚本在第一个响应中找不到它要查找的内容,则会启动第二个请求。继续执行后,它会设置背景图像。

进一步阅读:

另一种选择是使用回调。这种方法更难以遵循,但无处不在。

&#13;
&#13;
$.getJSON('https://jsonplaceholder.typicode.com/posts/1', post => {
    $.getJSON('https://jsonplaceholder.typicode.com/comments', comments => {
        post.comments = comments.filter(e => e.postId === post.id);
        console.log(post);
    });
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

$.getJSON(InternalURL, function (data) {
     $.each(data.Source, function (index, value) {
           if(artist.includes(value.keyword)){
                 if (value.image) {
                     image = value.image;
                     $(".bg").css("background-image", "url(" + image + ")");
                 } else {
                     $.getJSON(ExternalURL, function (data) {
                         image = data.artist.image;
                         (".bg").css("background-image", "url(" + image + ")");
                     });
                 }
           }
     });
 });